Android 利用正则+反射+SpannableString展示Emoji表情
简单实现一下,仅供参考,先给一张图片~~
- 先说下实现的步骤
- 1.从输入的字符串中获取匹配emoji表情名称的子字符串
- 2.利用R.mipmap.class来找到该emoji名称对应的Rid
- 3.利用Rid获取到对应的Drawable
- 4.emoji Drawable转换成ImageSpan
- 5.将原字符串转换成SpannableString,并在读取到的Emoji位置把ImageSpan替换上去
- 6显示在TextView上即可
- 1将众多emoji表情导入mipmap文件夹下,并且名称为“emoxxx”
- 2.布局如下,TextView 和EditText
<?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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"/>
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:inputType="text"/>
</LinearLayout>
- 3.代码如下
public class MainActivity extends AppCompatActivity implements TextWatcher {
private TextView tv;
private EditText et;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
et = (EditText) findViewById(R.id.et);
et.addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
changeStrWithEmoji(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
String TAG = "TAG";
public void changeStrWithEmoji(String input) {
//1.匹配字符串input中“[xxx]”
Pattern pattern = Pattern.compile("\\[[^\\[\\]]*\\]");
//2.获取匹配器
Matcher matcher = pattern.matcher(input);
//3.创建SP
SpannableString sp = new SpannableString(input);
//4.依次找到字符串input匹配到的子字符串
while (matcher.find()) {
//5.获取匹配到的子字符串[emoxxx]
String group = matcher.group();
//6.在该字符串开始的位置 与结束的位置
int start = matcher.start();
int end = matcher.end();
Log.d(TAG, group);
//7.获取 R.mipmap.class 实例
Class<R.mipmap> mipmapClass = R.mipmap.class;
try {
//8.去掉[emoxxx] 中括号查找 定义的变量
Field field = mipmapClass.getDeclaredField(group.substring(1, group.length() - 1));
//9 R.mipmap.class 定义的变量都是 static的 可直接获取
int rid = field.getInt(null);
Log.d(TAG, rid + "");
//10.获取该[emoxxx]对应的emo Drawable
Drawable drawable = getResources().getDrawable(rid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
//11.在指定的位置设置该 ImageSpan即可
sp.setSpan(new ImageSpan(drawable), start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
} catch (Exception e) {
e.printStackTrace();
}
}
//12.显示出来
tv.setText(sp);
}
}
- 完~~