编辑EditText输入实现标签显示的样式

wei880206 7年前
   <p>最近朋友的项目遇到一个需求,就是在EditText中输入后 按一下空格 然后前面输入的内容就自动根据空格分组并且高亮显示出标签样式,百度了一下 居然没有搜到类似的工具,看来还的自己动手,没图说了谁信?先看效果图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/6e0e20d2cbeb9f0f9acafcd391b84974.png"></p>    <p style="text-align:center">Paste_Image.png</p>    <p>其实原理很简单,根本不需要自定义什么乱七八糟的View,就利用现成的API就能实现效果,xml文件就不贴了,就一个EditText,自己脑补,下面主要说一下核心代码一个类:</p>    <p>1.首先肯定是初始化EditText以及需要用的变量</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ab232cb6bd17a1fa70a2f1e95cad046a.png"></p>    <p style="text-align:center">Paste_Image.png</p>    <pre>  <code class="language-java">/** * 需要监听的输入框 */private EditText mEditText;/** * 记录下上次的文本长度 */private int length=0;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    mEditText = (EditText) findViewById(R.id.text);    mEditText.addTextChangedListener(this);    mEditText.setOnKeyListener(this);}</code></pre>    <p>通过代码或者截图发现肯定要实现两个接口,一个是监听EditText文本输入,一个是软键盘的删除键监听</p>    <p>2.实现输入文本内容监听</p>    <p>TextWatcher有三个函数需要我们实现:</p>    <p>beforeTextChanged输入之前的状态(一会用到)</p>    <p>onTextChanged输入中状态和文本变化(这里用不到)</p>    <p>afterTextChanged输入结束后的状态(这里主要实现的地方)</p>    <p>首先记录下输入文本之前的内容长度</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a8ff190021805967871d6fe16584a22f.png"></p>    <p style="text-align:center">Paste_Image.png</p>    <p>length是一个int的类型,前面代码有定义</p>    <p>3.监听到文本输入结束后判断最后一位是不是输入了空格进行标签样式显示</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4e4bc0b30d00dea39f1628e4c6392e1a.png"></p>    <p style="text-align:center">Paste_Image.png</p>    <pre>  <code class="language-java">/** * 核心步骤 * 主要通过SpannableString来实现标签分组 */private void onSetSpan(){    String content = mEditText.getText().toString();    SpannableString spannable = new SpannableString(content);    //通过空格来区分标签    String[] m = content.split(" ");    int start = 0;    int end;    for (String str : m) {        end = start + str.length();        spannable.setSpan(new BackgroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);        spannable.setSpan(new ForegroundColorSpan(Color.WHITE), start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);        start = end + 1;    }    mEditText.setText(spannable);    //设置完成后 需要把焦点移动到最后一位    mEditText.setSelection(spannable.length());}</code></pre>    <p>是不是很简单,只需要想明白逻辑就能实现你想要的,这里主要核心方法SpannableString分割字符串的样式进行分别高亮显示,SpannableString可以实现很多功能,具体的内容自己去查看资料(这不是我们的重点)。</p>    <p>上面实现了内容标签化分组,那么删除怎么玩呢?肯定也要按照标签删除,一次删除一个标签内容,而不是一个个字符删除,这下我们OnKeyListener就有作用了,怎么删除按照标签删除?直接上代码上图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5c80f791660faebe81c9e02a80703889.png"></p>    <p style="text-align:center">Paste_Image.png</p>    <pre>  <code class="language-java">/** * 监听返回键,按照标签组删除 * @param v * @param keyCode * @param event * @return */@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {    String content = mEditText.getText().toString();    if(content.length()>0){        String last = content.substring(content.length()-1,content.length());        if(keyCode == KeyEvent.KEYCODE_DEL && !last.equals(" ")){            String[] m = content.split(" ");            String lastTag = m[m.length-1];            content = content.substring(0,content.length()-lastTag.length());            mEditText.setText(content);            return true;        }    }    return false;}</code></pre>    <p>总结:这样就能满足基本需求了,但是发现是不是标签有点丑,也许根本达不到设计的要求,那怎么做出漂亮的标签显示呢?下次再说(核心还是在SpannableString上面)。先吃饭才是王道。</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/67543f129a15</p>    <p> </p>