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

摘要:
(3) 如何解决1.如何在每行文本下面都有一行?首先,您需要获得文本行数并使用EditText。getLineCount();然后画一条线。2.如何确定水平线的位置?

之前写了一个关于实现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只能显示高度不超过屏幕高度的文本内容,继续增加内容会出现如下问题:

Android实现带下划线的EditText(BUG修正)第1张

(二)原因分析

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

(三)如何解决

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,行距的存在影响了视图效果,加上半行距就好]

Android实现带下划线的EditText(BUG修正)第2张

Android实现带下划线的EditText(BUG修正)第3张

(六)总结

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

免责声明:文章转载自《Android实现带下划线的EditText(BUG修正)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇替代eval的方法Java在处理大数据的时候一些小技巧下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

彻底解决Mac无线网络故障和网速慢的问题

应该可以上网了。这个方法就是完全重置你电脑的控制器了,会将设置都恢复初始化,但是不影响硬盘数据,不必备份。很多时候macbook出现莫名其妙的问题都用得上。...

docker安装宝塔

主机的/home/www文件夹映射到docker容器的/www(注意:如果文件目录不存在,特权意味着在运行容器时,容器被授予特权,容器有权写入文件。然后问题来了……安装完成后,如果重新启动容器,容器宝塔会丢失吗?不,让我们试试:...

为服务中网关的作用

“API网关”核心组件是架构用于满足此些需求。API网关定位为应用系统服务接口的网关,区别于网络技术的网关,但是原理则是一样。API网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。...

java报表实现excel一样冻结表头的功能

增加了几个新的指标,后台sql改了,拿过来只须在一个dao类中修改就足够了,可恨的是客户又提出来改报表表样,加个类似excel冻结表头的功能。...

Spark 数据读取与保存(输入、输出)

SaveAsTextFile(字符串)scala&gt:importsscala.util.parsing.json.json(2)将json文件上载到HDFS[lxl@hadoop102spark]$hadoopfs投入。/示例/src/main/resources/people。json/(3)读取文件scala&gt;...

数据可视化之powerBI技巧(十四)采悟:PowerBI中自制中文单位万和亿

最令人不快的事情之一是数据单元的设置。现在让我们看看如何通过设置测量值来切换单位。需要动态选择1万元和1亿元的单位进行显示。首先,手动创建单位表,然后使用单位表中的[unit]字段生成切片器。下一步是建立销售衡量标准。销售额=总和('订单'[销售额])为了按过滤单位显示销售额,SELECTEDVALUE函数可以根据切片器选择动态更改分母。如果切片器未进行任何...