作者:丶原色调 | 来源:互联网 | 2023-10-12 18:03
简述
自己封装一个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 &#61; false;public ExpressionEditText(Context context) {super(context);}public ExpressionEditText(Context context, AttributeSet attrs) {super(context, attrs);init(context, attrs);}&#64;Overridepublic void setText(CharSequence text, BufferType type) {super.setText(text, type);}/*** 删除一个字符或删除一个表情*/public void deleteOne() {Editable editable &#61; this.getText();int len &#61; editable.length();if (len <1) {return;}if (isEmojiEnd) {editable.delete(len-4, len);} else {editable.delete(len-1, len);}}/*** 初始化* &#64;param context* &#64;param attrs*/private void init(Context context, AttributeSet attrs) {addTextChangedListener(new TextWatcher() {int type &#61; 0; &#64;Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {if (after > count) {type &#61; 0;Log.d("ExpressionEditText", "增加字符");} else {type &#61; 1;Log.d("ExpressionEditText", "删减字符");}Log.d(TAG, "beforeTextChanged: strat&#61;" &#43; start &#43; ",count&#61;" &#43; count &#43; " ,after&#61;" &#43; after);}&#64;Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}&#64;Overridepublic void afterTextChanged(Editable s) {isEmojiEnd &#61; false;String regex &#61; "\\[(.*?)\\]";Pattern pattern &#61; Pattern.compile(regex);Matcher matcher &#61; pattern.matcher(s.toString());while (matcher.find()) {int start &#61; matcher.start();int end &#61; matcher.end();if (end &#61;&#61; s.length()) {isEmojiEnd &#61; true;}Log.d("匹配结果", matcher.group(0) &#43; "," &#43; matcher.group(1));String id &#61; matcher.group(1);int drawableId &#61; R.drawable.p1;switch (id) {case "p1":drawableId &#61; R.drawable.p1;break;case "p2":drawableId &#61; R.drawable.p2;break;case "p3":drawableId &#61; R.drawable.p3;break;}ImageSpan span &#61; new ImageSpan(getContext(), drawableId, DynamicDrawableSpan.ALIGN_BASELINE);s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}}});}
}
项目问题&#xff1a;由于每一次TextChange都需要使用正则来搜索一遍输入的字符串&#xff0c;将其中[]格式的字符转为表情&#xff0c;这样导致的问题就是用户无法快速删除输入表情&#xff0c;用户体验非常不好&#xff01;