Android实现自带横线的EditText

摘要:
(1) 如何使用水平条实现EditText?但在这个过程中,我学到了9patch图像的有用性,这是一个小小的收获。

(一)问题

怎样实现带有横栏的EditText(像记事本的编辑界面那样)?

(二)初步思路

1.通过修改EditText背景来实现(系统背景是一个框形图片,内部透明,替换为一个带有横栏的图片即可)

2.通过重绘EditText来实现(自定义组件,自己画线)

3.用ListView实现(ListView本身就会显示横线)

(三)深入分析

1.EditText显示多行文本时会自动拉伸背景,若要保证边框不会失真,需要用9patch图片来做背景,或许能够实现

2.毫无疑问,自定义EditText一定可以实现横线的显示(没有枪炮就自己造...),但是自定义组件比较麻烦(需要重写很多东西),能用其他方法解决当然更好

3.ListView用来显示多行文本可能比较好(将Text分割为等长String存入Array,作为ListView的Adapter),但是若要编辑文本则明显不合适

(四)初步实践

1.通过多次测试发现改变EditText的背景图能够显示横栏,但仅限于SingLine的文本,因为输入多行文本时背景图会向下拉伸(横线没了...)。所以测试结果是:用自定义背景图只能显示带下划线的单行文本,方案一失败!但是在此过程中学到了9patch图片的用处,算是一点小收获。

2.通过重写EditText的onDraw方法来绘制需要的横线,如何确定横线的位置成为核心问题(本质是获取一组起点坐标和一组对应的终点坐标),此方法在下面展开详述

3.ListView的缺点在上面已经说过了,但是经过对方案一的尝试,我们很容易发现方案一和方案三恰好互补(把方案一得到的EditText作为ListView的Item),此时应该为EditText自定义selector,设置focus时不发光即可。测试结果是:单行EditText负责按行显示文本,ListView负责画线,方案一组合方案三可行。

(五)自定义EditText实现横栏的显示

[自定义myEditText类]

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 = 2f;//宽度为2
	}
	
	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 w = this.getWidth();//获取控件宽度
		int h = this.getHeight();//获取控件高度
		int padB = this.getPaddingBottom();//获取底部留白
		int padL = this.getPaddingLeft();//获取左边留白
		int padR = this.getPaddingRight();//获取右边留白
		float size = this.getTextSize() * 7 / 6;//获取横栏间距(TextSize的默认值为18)
		/*设置size的值是一个核心问题,size的值要适应不同的字体大小(不同大小字体的行距也不同)
		 *经过多次尝试发现以字体大小的7/6倍作为横栏间距最合适
		 * */
		int lines = (int)(h / size);//获取行数
		
		//从下向上画线
		for(int i = 0;i < lines;i++)
			canvas.drawLine(padL//startX
					, this.getHeight() - padB - size * i//startY
					, this.getWidth() - padR//endX
					, this.getHeight() - padB - size * 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;
	}

}

[布局文件]

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android: 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

</LinearLayout>

[测试类]

package com.ayqy.app_test;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.LinearLayout;

public class MainActivity extends Activity {
	
	LinearLayout root;//声明根布局

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		root = (LinearLayout) findViewById(R.id.root);//获取根布局
		//创建自定义EditText控件对象
		myEditText txt = new myEditText(this);
		//设置多行文本
		txt.setText("这是一个很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的测试内容");
		//用来测试是否能够适应不同大小的字体
		//txt.setTextSize(48);
		//txt.setTextSize(24);
		root.addView(txt);//添加控件
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

[P.S.以上源码本机测试无误,若在测试中发现任何问题请在下方留言]

(六)测试结果图片

Android实现自带横线的EditText第1张

Android实现自带横线的EditText第2张

Android实现自带横线的EditText第3张

(七)总结

尝试是解决问题的最好方法,即便最终问题得不到解决,其间的思考也是一种锻炼

(八)BUG修正

此版本存在BUG,详情及修正方法见 http://www.cnblogs.com/ayqy/p/3600289.html

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

上篇MySQL 的Coalesce函数centos7.5 虚拟机启动卡在开机界面不动下篇

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

随便看看

Zabbix故障处理系列

然后,您还需要重新启动zabbix porxy。我刚重启了zabbix特工。然而,Zabbix网络界面的图形中没有数据。此时,重新启动zabbix代理以解决相应的问题。Zbx在Zabbix监控的网页上也显示为灰色。有时,其中一些可能是绿色的,如下所示:问题2:当Zabbix代理未升级时,无法在Zabbix监控页面上监控数据。原因:ZABBIX4.0版本存在兼...

无法将您的Kindle连接到Wi-Fi网络怎么办-kindle无法连接wifi-kindle无法连接手机热点

问题描述:当连接到Wi-Fi或移动热点时,Kindle会弹出提示:如果我无法将您的Kindle连接到Wi-Fi网络,该怎么办。步骤1:通过USB数据线将Kindle连接到计算机。2.连接后,我电脑的磁盘将像一个USB闪存驱动器,Kindle磁盘将出现在其中。3.进入Kindle磁盘。在Kindle磁盘下,右键单击创建一个名为WIFI_NO_NET_PROBE...

微软新一代输入法框架 TSF

目前,市场上的非微软中文输入法基本上只实现IMM框架。自Windows XP开始以来,Windows提供了一个基于COM的新输入框架TSF。但是,Windows Vista和Windows 7用户也可以使用各种基于IMM的输入方法,因为Windows提供了一个组件来将所有TSF请求转换为IMM API。很可能,因为Win8下的许多Imm函数无法使用。)根据微...

5G中的频点计算及实例分析

相关图表:关于∏SSB的频域位置SSREF和GSCN之间的关系,请参见下表:注:SCSspacedchannelrasterisM=3的工作频带的默认值。同步网格是5G的第一个概念,旨在加快终端扫描SSB的频率位置。GSCN通常用于在SA联网模式下加速时频同步,以继续解释MIB和SIB1消息;对于NSA来说,这是不必要的。RRC重配置消息已经携带了NR的SS...

iphone的mov文件复制到电脑的方法

解决方案:1.对于iPhone-˃设置-˃照片,将底部选项“传输到MAC或PC”从“自动”更改为“保持原始”。...

删除隐藏网卡(本机IP地址被占用)4个方法

关闭注册表,重新启动windowsxp或重新登录,在设备管理器中单击查看->显示隐藏设备,展开“网络适配器”卸载原来的老网卡,在重设IP就不会显示IP地址被占用了。方法2:要删除系统中隐藏的网卡,我们必须运行regedit打开注册表编辑器,找到HKEY_LOCAL_MCHINE\SYSTEM\CurrentControlSetControl\Network\...