Android EditText表情输入的探索

简述

自己封装一个EditText(实际上只是在EditText内部添加了一个TextWatcher),监听文本改变,将其中的“[..]”类型的文本替换为表情

先说一下在编写中遇到的一个问题:

Drawable drawable = getResources().getDrawable(p1, null);
ImageSpan span = new ImageSpan(drawable, DynamicDrawableSpan.ALIGN_BASELINE);
s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

这里获取出来的ImageSpan是显示不出来的!

使用这个方法时,必须设置drawable的边界

drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                            drawable.getIntrinsicHeight());

或者使用ImageSpan的另一个构造方法:

ImageSpan span = new ImageSpan(getContext(), R.drawable.p1, DynamicDrawableSpan.ALIGN_BASELINE);

项目

image

(效果图)

package com.momingqi.wedget;

import android.content.Context;
import android.text.Editable;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;

import com.momingqi.R;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static android.content.ContentValues.TAG;


/**
 * 可输入表情的输入框控件
 * @author mingC
 * @date 2018/4/2
 */
public class ExpressionEditText extends android.support.v7.widget.AppCompatEditText{

    /**
     * 当前输入框是否是表情结尾
     */
    private boolean isEmojiEnd = false;

    public ExpressionEditText(Context context) {
        super(context);
    }

    public ExpressionEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(text, type);
    }

    /**
     * 删除一个字符或删除一个表情
     */
    public void deleteOne() {
        Editable editable = this.getText();
        int len = editable.length();
        if (len < 1) {
            return;
        }
        if (isEmojiEnd) {
            //删除一块
            editable.delete(len-4, len);
        } else {
            editable.delete(len-1, len);
        }
    }

    /**
     * 初始化
     * @param context
     * @param attrs
     */
    private void init(Context context, AttributeSet attrs) {
        addTextChangedListener(new TextWatcher() {
            int type = 0;   //0->append,1->delete

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                if (after > count) {
                    type = 0;
                    Log.d("ExpressionEditText", "增加字符");
                } else {
                    type = 1;
                    Log.d("ExpressionEditText", "删减字符");
                }
                Log.d(TAG, "beforeTextChanged:  strat=" + start + ",count=" + count + " ,after=" + after);
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                //初始化标志
                isEmojiEnd = false;
                String regex = "\\[(.*?)\\]";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher(s.toString());
                while (matcher.find()) {
                    int start = matcher.start();
                    int end = matcher.end();
                    if (end == s.length()) {
                        isEmojiEnd = true;
                    }
                    Log.d("匹配结果", matcher.group(0) + "," + matcher.group(1));
                    String id = matcher.group(1);
                    int drawableId = R.drawable.p1;
                    switch (id) {
                        case "p1":
                            drawableId = R.drawable.p1;
                            break;
                        case "p2":
                            drawableId = R.drawable.p2;
                            break;
                        case "p3":
                            drawableId = R.drawable.p3;
                            break;
                    }
                    ImageSpan span = new ImageSpan(getContext(), drawableId, DynamicDrawableSpan.ALIGN_BASELINE);
                    s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        });
    }
}

项目问题:由于每一次TextChange都需要使用正则来搜索一遍输入的字符串,将其中[]格式的字符转为表情,这样导致的问题就是用户无法快速删除输入表情,用户体验非常不好!

猜你喜欢

转载自blog.csdn.net/mingc0758/article/details/80102275