自定义EditText画任意行线并限制文本的物理长度

项目中有个需求 就是需要EditText变为两行显示 而且当文字写到第二行末尾的时候要提示文字已达限制。


 1. EditText本身没有自带的行线 所以需要自己自定义 画出自己需要的行线。这里我是在网上一个盆友那儿找的一段代码 自己修改了下,效果出来了。(谢谢那位朋友,因为当时很急没来得及收藏链接,抱歉)

public class UnderLineEditText extends EditText {  
      
    private Paint linePaint;  
    private int paperColor;  
  
    public UnderLineEditText(Context context,AttributeSet paramAttributeSet) {  
        super(context,paramAttributeSet);  
        // TODO Auto-generated constructor stub  
        this.linePaint = new Paint();  
        linePaint.setColor(Color.GRAY);//设置下划线颜色  
        linePaint.setStrokeWidth(2);
    }  
      
    protected void onDraw(Canvas paramCanvas) {  
        paramCanvas.drawColor(this.paperColor); //设置背景色  
        int i = getLineCount();  //行数
        int j = getHeight();     //View的高度
        int k = getLineHeight(); // 
        int m = 1 + j / k;  
        if (i < m) i = m;  
        int n = getCompoundPaddingTop();  
         //此处调整 画线的位置...用DP 避免手机分辨率的影响
        int distance_with_btm=(int) (getLineHeight()-getTextSize())-dip2px(getContext(), 5);  
        //int distance_with_btm=(int) (getLineHeight()-getTextSize())-3;  
        //这个关于距离底部的变量当不使用lineSpacingMultiplier和lineSpacingExtra参数时是不起作用的  
  
        for (int i2 = 0;; i2++) {  
            if (i2 >= i) {  
                super.onDraw(paramCanvas);  
                paramCanvas.restore();  
                return;  
            }  
            n += k;  
            n-=distance_with_btm;//将线划在字体靠下面  
            paramCanvas.drawLine(0.0F, n+10, getRight(), n+10, this.linePaint);  
            paramCanvas.save();  
            n+=distance_with_btm;//还原n  
        }  
    }  
    /************************ DP PX 转换 **************************************/
	/**
	 * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
	 * 
	 * @param context
	 *            Context对象
	 * @param dpValue
	 *            dp值
	 * @return int px值
	 */
	public static int dip2px(Context context, float dpValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dpValue * scale + 0.5f);
	}
  
}  

对应在xml中的代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <com.example.twolineedittext.UnderLineEditText
            android:id="@+id/et_line"
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:background="@null"
            android:ems="10"
            android:gravity="top"
            android:imeOptions="actionDone"
            android:inputType="textMultiLine"
            android:lineSpacingMultiplier="1.5"
            android:maxLines="2" 
            >
            <requestFocus />
        </com.example.twolineedittext.UnderLineEditText>

</RelativeLayout>
这里需要注意一下的是 固定EditText的高度 就可以让它显示到自己所需要的行数,运行效果如下图


看上去 效果达到了。但是当第二行继续输入的时候可以一直不停的输入。然后直接设置EditText 的 maxLength 属性。但是中文和英文的长度是不一样的。我想很多盆友也受到过和我一样的苦恼吧。然后去找度娘 看到了一个方法可以获取到EditText的物理像素长度,个根据自己的需求运用到EditText中 当文本输入到编辑框末尾的时候弹出提示字数达到限制,这里判断物理长度 而不是文本长度。代码如下:

public class MainActivity extends Activity {

	EditText et_line;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		et_line=(EditText) findViewById(R.id.et_line);
	}
	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
		//这个TextView的长度 和EditText的长度一样 。获取此长度方便进行比较
		TextView line = (TextView) findViewById(R.id.line);
		final int width = line.getWidth();
		//监听文本框的文本改变
		et_line.addTextChangedListener(new TextWatcher() {
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				//如果第二行还剩15dp的时候便提示字数达到限制 
				if (getTextWidth(et_line) >= (width * 2 - UnderLineEditText.dip2px(
						getApplicationContext(), 15))) {
					
					Toast.makeText(MainActivity.this, "字数已达限制",0).show();
					//获取文本来设置编辑框限制的文本长度
					et_line.setFilters(new InputFilter[]{new InputFilter.LengthFilter(et_line.getText().toString().length())});  
					
				} 
			}
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}
			public void afterTextChanged(Editable s) {
			}
		});//点击Enter不执行跳行。
		et_line.setOnKeyListener(new OnKeyListener() {
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (keyCode == 66) { // ENTER
					return true;
				}
				return false;
			}
		});
	}
	/**
	 * 获取输入框的物理长度
	 * @param et
	 * @return
	 */
	public int getTextWidth(EditText et) {
		// 得到输入框的物理长度
		TextPaint paint = et.getPaint();
		float textWidth = paint.measureText(et.getText().toString());
		return (int) textWidth;
	}
}
运行效果如下图:


自己记下或许以后用得到,也希望能帮到和我一样的朋友们。最后附上Demo下载地址:http://download.csdn.net/detail/yangbo437993234/8851841

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值