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

Posted IyangcLove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义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

以上是关于自定义EditText画任意行线并限制文本的物理长度的主要内容,如果未能解决你的问题,请参考以下文章

需要为EditText长触摸而不是ActionMode自定义弹出窗口

自定义ANDROID中EDITTEXT中的HINT文本的大小

cad中怎么画平行线

在CAD中,如何画两条平行线的中心线?

Edittext 在长按时进行选择但不显示上下文菜单?

将EditText过滤器设置为自定义范围内的数字