• Android实现带下划线的EditText(BUG修正)


    之前写了一个关于实现EditText显示下划线的例子,发现仍然存在一些问题,在此继续探索,原文链接:http://www.cnblogs.com/ayqy/p/3599414.html

    (零)另一个bug

    如果发现画不出线,那么可能是canvas.drawLine方法最后一个参数paint的线宽的bug,Android2.3.5中线宽为0.5可以正常画线,Android4.2.2中线宽为0.5无法画线,具体如下:

    /**注意线宽,Android2.3.5中线宽为0.5可以正常画线,Android4.2.2中线宽为0.5无法画线**/
    lineWidth = 1.0f;//默认宽度为1.0
    

    如果还是画不出线,则检查起点坐标,画线时如果起点不在可见范围内则整条线不可见,TextView的可见区域是控件占据的矩形区域,具体如下:

    /*画线时如果起点不在可见范围内则整条线不可见,TextView的可见区域是控件占据的矩形区域*/
    canvas.drawLine(padL//startX
    		, baseTop + gap * i//startY
    		, this.getWidth() - padR//endX
    		, baseTop + gap * i//endY
    		, mPaint);

    (一)问题

    之前的自定义EditText只能显示高度不超过屏幕高度的文本内容,继续增加内容会出现如下问题:

    (二)原因分析

    下部(超出屏幕高度的部分)没有继续画线,也就是说横线没有画够,那么一定是循环控制部分出了问题。

    (三)如何解决

    1.怎么才能做到每行文字下方都有一条线?

    那么首先需要获取文本的行数用EditText.getLineCount();再按行画线即可

    2.怎么确定横线的位置?

    Y = EditText.getPaddingTop() + EditText.getLineHeight() * index;//Y坐标 = 文本框内上部留白 + 行宽 * 行索引(第几行)

    上面的方法是从上往下画线,当然也可以从下往上画线,在此不展开叙述

    (四)编码

    [自定义EditText]

    package com.ayqy.app_test;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.widget.EditText;
    
    public class myEditText extends EditText{
    
    	private int lineColor;//横线颜色
    	private float lineWidth;//横线宽度
    
    	public myEditText(Context context) {
    		super(context);
    
    		//设置默认颜色和横线宽度
    		lineColor = Color.BLUE;//默认蓝色线
    		lineWidth = 0.5f;//默认宽度为0.5
    	}
    
    	public myEditText(Context context,int color,float width) {
    		super(context);
    
    		//设置颜色和横线宽度
    		this.lineColor = color;
    		this.lineWidth = width;
    	}
    
    	@Override
    	protected void onDraw(Canvas canvas) {
    		// TODO Auto-generated method stub
    		super.onDraw(canvas);
    
    		//创建画笔
    		Paint mPaint = new Paint();
    		mPaint.setStrokeWidth(lineWidth);
    		mPaint.setStyle(Paint.Style.FILL);
    		mPaint.setColor(lineColor);
    
    		//获取参数
    		int padL = this.getPaddingLeft();//获取框内左边留白
    		int padR = this.getPaddingRight();//获取框内右边留白
    		int padT = this.getPaddingTop();//获取框内顶部留白
    		int lines = this.getLineCount();//获取行数
    		float size = this.getTextSize();//获取字体大小
    		float baseTop = padT + size / 6;//从上向下第一条线的位置
    		/*这里需要说明的是size/6这个值,是偶然测试得到的,近似于行距的一半
    		 *为什么不用EditText.getLineSpacingExtra();来获取行距?
    		 *因为测试发现若调用EditText的getLineSpacingExtra方法会报NoSuchMethod错误,具体原因不明
    		 *测试发现行距的值近似于TextSize的1/3,在需要用到行距的时候可以用这个值来代替getLineSpacingExtra方法
    		 * */
    		float gap = this.getLineHeight();//获取行宽
    		
    		//从上向下划线
    		for(int i = 1;i <= lines;i++)
    		{
    			canvas.drawLine(padL//startX
    					, baseTop + gap * i//startY
    					, this.getWidth() - padR//endX
    					, baseTop + gap * i//endY
    					, mPaint);
    		}
    	}
    
    	public int getLineColor() {
    		return lineColor;
    	}
    
    	public void setLineColor(int color) {
    		this.lineColor = color;
    	}
    
    	public float getLineWidth() {
    		return lineWidth;
    	}
    
    	public void setLineWidth(float width) {
    		this.lineWidth = width;
    	}
    
    }
    

    P.S.上方的代码注释提到了“测试发现若调用EditText的getLineSpacingExtra方法会报NoSuchMethod错误”,Google之后发现好像没人遇到过这个问题,如有朋友知道答案请在下方留言,谢谢

    (五)效果截图

    [改进之后的代码完美解决了“文字压线”和“光标压线”的问题,核心就是行距=TextSize/3,行距的存在影响了视图效果,加上半行距就好]

    (六)总结

    发现Bug及时修改,programming的乐趣就在这里了

  • 相关阅读:
    WPF 进度条
    WPF CPU使用率线性表
    Android annotation
    git 操作
    git 合并指定目录到master
    远程连接mysql报错,ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)解决方案
    centos7 安装python2.7.14 并与原版本共存
    pycahrm 断点调试
    ImportError: No module named Crypto.Cipher 报错解决方法
    python操作 rabbitMQ
  • 原文地址:https://www.cnblogs.com/ayqy/p/3600289.html
Copyright © 2020-2023  润新知