Android EditText 文本内容超过文本框失去焦点后,超出文本框内容显示...

来源:互联网 发布:mac上的杀毒软件 编辑:程序博客网 时间:2024/06/05 09:01
产品OR测试提出优化需求,输入的文字长度超过输入框,则超出的文本用…显示,当获取焦点的时候,显示全部内容,光标又要移动到最后。

思路:
    1、第一想到的肯定是“ellipsize”属性设置为“end”,android:ellipsize=“end”。这个在文本框TextView有效,EditText未起作用,亲测。
    2、设置固定宽度,或者看下固定文字,比如你设定的文本框只能显示十个中文字符就占满了,但如果输入了英文或者数字则长度又不好计算了,并且测试那还有N种手机屏幕在那等着来轮奸你呢,早点放弃为好!

    3、得到输入文本框EditText的宽度,得到字符串的宽度,然后对比,字符串宽度>文本框宽度,就substring掉。这目前应该是最好的了方案了,并且Android提供了计算文本宽度的方法。

第一次尝试着写文章,排版逻辑什么的不怎么规范,还请多包涵!

开干:
    建项目就略了。

1、布局文件:activity_main.xml
           
Code Text:
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout 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"
    android:background="#f2f2f2
    android:focusable="true"
    android:focusableInTouchMode="true"
    tools:context="com.threefei.rou.MainActivity">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        android:scrollbarSize="0dp"
        android:scrollbars="none">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="@android:color/white"
                android:orientation="horizontal"
                android:paddingLeft="15dp"
                android:paddingRight="15dp">

                <TextView
                    android:layout_width="100dp"
                    android:layout_height="match_parent"
                    android:gravity="center_vertical"
                    android:text="收件人地址:"/>

                <EditText
                    android:id="@+id/et_address_1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@null"
                    android:gravity="center_vertical"
                    android:maxLength="30"
                    android:maxLines="1"
                    android:singleLine="true"
                    android:textSize="12sp"/>

            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="0.5dp"
                android:background="@android:color/darker_gray"/>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="@android:color/white"
                android:orientation="horizontal"
                android:paddingLeft="15dp"
                android:paddingRight="15dp">

                <TextView
                    android:layout_width="100dp"
                    android:layout_height="match_parent"
                    android:gravity="center_vertical"
                    android:text="发件人地址:"/>

                <EditText
                    android:id="@+id/et_address_2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@null"
                    android:gravity="center_vertical"
                    android:maxLength="30"
                    android:maxLines="1"
                    android:singleLine="true"
                    android:text=""
                    android:textSize="12sp"/>

            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="0.5dp"
                android:background="@android:color/darker_gray"/>

            <TextView
                android:id="@+id/tv_result"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:background="@android:color/white"
                android:hint="提交结果值"
                android:padding="10dp"
                android:minHeight="150dp"/>

            <Button
                android:id="@+id/btn_click"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:layout_margin="25dp"
                android:gravity="center"
                android:text="提交"/>

        </LinearLayout>
    </ScrollView>
</LinearLayout>

Code Design:

2、Activity:MainActivity.java
    1)按产品的要求,那肯定得设置EditText的setOnFocusChangeListener。
    2)获得焦点的时候,得把原来超过长度范围值(原始值)设置到setText(String val),这个原始值,可以放到外面的成员变量里,也可以放到EditText的tag里,这里的tag还没有其他用途,所以我把值放到tag里。
    3)失去焦点的时候,得判断输入框的字符串是否大于控件的宽度,大于则截掉超出范围的字符串。
         a. EditText.setSelection(int index) 可以把光标定位到某个文字后面
         b. TextView.getPaint().measureText(String text)可以得到字符串的宽度
         c. 循环计算追加每个字符串的长度 > 文本框的长度
         d. 最后substring


public classMainActivityextendsActivityimplementsView.OnClickListener,View.OnFocusChangeListener {

   private static final intCODE_MSG_ADDRESS_1=1;
    private static final intCODE_MSG_ADDRESS_2=2;

    privateEditTextmEtAddress1,mEtAddress2;
    privateTextViewmTvResult;

   @Override
   protected voidonCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       mEtAddress1= (EditText) findViewById(R.id.et_address_1);
       mEtAddress2= (EditText) findViewById(R.id.et_address_2);

       //提前先设置tag,避免在onFocuse里出现对象转换异常
       mEtAddress1.setTag("");
       mEtAddress2.setTag("");

       mEtAddress1.setOnFocusChangeListener(this);
       mEtAddress2.setOnFocusChangeListener(this);

       mTvResult= (TextView) findViewById(R.id.tv_result);

       findViewById(R.id.btn_click).setOnClickListener(this);
   }

   @Override
   public voidonWindowFocusChanged(booleanhasFocus) {
       super.onWindowFocusChanged(hasFocus);
        if(hasFocus) {
           //Activity的话,初始化赋值,可以在onWindowFocusChanged里设置,执行到这,控件的宽高可以得到了
            //这个val可以从其他地方传过来
           String val ="幸福省幸福市幸福区幸福路幸福小区x栋xx号";
           formartEditTextViewVal(mEtAddress2,val);
       }
    }


   @Override
   public voidonClick(View v) {
       mEtAddress1.clearFocus();
       mEtAddress2.clearFocus();

       //真实的值放到了tag里了
       String address1 =mEtAddress1.getTag().toString();
       String address2 =mEtAddress2.getTag().toString();

       StringBuilder sb =new StringBuilder("收件人地址:").append(address1);
       sb.append("\n发件人地址:").append(address2);

       mTvResult.setText(sb.toString());
   }

   @Override
   public voidonFocusChange(View v, booleanhasFocus) {
       switch(v.getId()) {
           caseR.id.et_address_1:
               if (hasFocus) {
                    String text =mEtAddress1.getTag().toString().trim();
                   mEtAddress1.setText(text);
                   mHandler.sendEmptyMessage(CODE_MSG_ADDRESS_1);

                   //直接在这里设置光标移动到最后,这句代码无效,所以用到Handler跳出该方法,再设置光标
//                    UITools.setEditTextCursorEnd(mEtAddress1);

               } else {
                    String text =mEtAddress1.getText().toString().trim();
                   formartEditTextViewVal(mEtAddress1,text);
               }
               break;

            caseR.id.et_address_2:
               if (hasFocus) {
                    String text =mEtAddress2.getTag().toString().trim();
                   mEtAddress2.setText(text);
                   mHandler.sendEmptyMessage(CODE_MSG_ADDRESS_2);

               } else {
                    String text =mEtAddress2.getText().toString().trim();
                   formartEditTextViewVal(mEtAddress2,text);
               }
               break;
       }
    }

   privateHandlermHandler= new Handler() {
       @Override
       public voidhandleMessage(Message msg) {
           super.handleMessage(msg);
            if(msg.what== CODE_MSG_ADDRESS_1) {
                UITools.setEditTextCursorEnd(mEtAddress1);

           } else if (msg.what== CODE_MSG_ADDRESS_2) {
                UITools.setEditTextCursorEnd(mEtAddress2);
           }
        }
    };

   /**
     * 格式化值
     *
     *@parameditText
    *@paramtext
    */
   private voidformartEditTextViewVal(EditText editText,String text) {
        editText.setTag(text);
       String str = UITools.getEllipsisValue(text,editText);
       editText.setText(str);
   }
}



补充下:使用Fragment初始化View获取控件宽高

/**
  * getViewTreeObserver的vto.addOnGlobalLayoutListener<br/>
  * 可以得到控件的宽高
  */
voidonGlobalLayout() {
   //向ViewTreeObserver 注册方法,以获取控件尺寸
   ViewTreeObserver vto =mEtAddress1.getViewTreeObserver();
   vto.addOnGlobalLayoutListener(newViewTreeObserver.OnGlobalLayoutListener() {
       public voidonGlobalLayout() {
           formartEditTextViewVal(mEtAddress1,"传递的值");
           mEtAddress1.getViewTreeObserver().removeGlobalOnLayoutListener(this);
       }
    });
}




3、工具类:UITools.java

public classUITools {
   /**
     * 将EditTextView的光标移动到最后
     *
     *@parameditText
    */
   public static voidsetEditTextCursorEnd(EditText editText) {
        editText.setSelection(editText.getText().toString().length());
   }

   /**
     * 获取字符串所占屏幕长度
     *
     *@paramtext
    *@paramtextView
    *@return
    */
   public static floatgetTextValueWidth(String text,TextView textView) {
       if (null== text ||"".equals(text)) {
           return0;
       }
        TextPaint textPaint = textView.getPaint();
        returntextPaint.measureText(text);
   }

   /**
     * 计算字符串宽度超过文本框宽度的时候,显示带...的字符串
     *
     *@paramtext
    *@paramtextView
    *@return
    */
   public staticStringgetEllipsisValue(String text,TextView textView) {
        String total ="";
        floattextViewWdith = textView.getWidth();
//        Log.e("xb", "-->文本框宽度:" + textViewWdith);
       booleanisCut =false;

        //循环计算追加后的字符串长度是否大于文本框长度
        for(inti =1;i <= text.length();i++) {
            total = text.substring(0,i);
            floattotalWdith =getTextValueWidth(total,textView);
//            Log.e("xb", "-->当前字符长度:" + totalWdith + ",字符串:" + total);
           if (totalWdith > textViewWdith) {
                isCut =true;
                break;
           }
        }

       //这里判断文本框长度是为了,有时候粗心,在view没有绘制好的时候,得到的宽度为0,不然substring就蹦了
       if (isCut && textViewWdith >0) {
           //可以截取3,但"..."占大概2个中文字符宽度左右
           returntotal.substring(0,total.length() -2) +"...";
       }
       returntext;
   }

   /**
     * Toast提示
     *
     *@paramcontext
    *@parammsg
    */
   public static voidshowToast(Context context,String msg) {
        Toast.makeText(context,msg,Toast.LENGTH_SHORT).show();
   }

}


4、运行效果图


这里可以重写EditText,把逻辑放到重写类里去,使用就方便多了。
其实在项目中,文本框输入还有N种需求,
1、屏蔽特殊字符,或者屏蔽表情符号
2、只能输入中文或者英文
3、带一键删除按钮的EditTextView等
4、银行卡类型的格式化输入等要求

小bug提示:有的手机,貌似是moto手机,你设置了maxLength = 10,但测试在输入法中一次性敲打超过十个字的文本,可以跳过maxLength的设置,所以又得监听addTextChangedListener了。

案例下载地址:http://download.csdn.net/download/liang_fei_xp/9968644
阅读全文
0 0
原创粉丝点击