简述
自己封装一个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);
项目
(效果图)
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都需要使用正则来搜索一遍输入的字符串,将其中[]格式的字符转为表情,这样导致的问题就是用户无法快速删除输入表情,用户体验非常不好!