一、 说明
说到聊天,就离不开文字、表情和图片,表情和图片增加了聊天的趣味性,让原本无聊的文字瞬间用表情动了起来,今天给大家带来的是表情键盘,教你一步一步实现,先来看下效果图.
二、功能
1、如何控制表情键盘与输入法的切换
2、如何解析表情
3、如何处理表情与非表情的删除
三、实现
明确了各个要解决的问题,下面我们逐个来实现
表情键盘与输入法切换
博主查了一下相关资料,有如下方案
方案一:动态改变SoftInputMode
软键盘显示时将SoftInputMode设置为「stateVisible|adjustResize」,表情键盘显示时调整为「adjustPan」
方案二:Dialog
直接在软键盘上显示一个Dialog,可避开大部分切换逻辑,但是在打开当前页面后存在软键盘和Dialog冲突问题
博主在观察QQ、微信、微博、陌陌后发现,他们的表情键盘和软键盘切换,并不会导致聊天内容(ListView、RecyclerView)的跳动,基本就可以推测SoftInputMode就是adjustsPan(SoftInputMode含义)
明确了adjustPan那就好办了,既然聊天内容(ListView、RecyclerView)不会跳动,那么在软键盘切换至表情键盘的时候,底部肯定有一个和软键盘高度一致的View,只需在点击表情的时候将软键盘隐藏,显示表情键盘,在点击EditText的时候显示软键盘,隐藏表情键盘。
来梳理一下知识点:
1、如何获取软键盘高度
2、如何手动控制软键盘的显示与隐藏
3、如何避免在别的页面切到当前界面因软键盘的状态变化而冲突
获取软键盘高度
private int getSupportSoftInputHeight() {
Rect r = new Rect();
mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
int screenHeight = mActivity.getWindow().getDecorView().getRootView().getHeight();
int softInputHeight = screenHeight - r.bottom;
if (Build.VERSION.SDK_INT >= 20) {
// When SDK Level >= 20 (Android L),
// the softInputHeight will contain the height of softButtonsBar (if has)
softInputHeight = softInputHeight - getSoftButtonsBarHeight();
}
if (softInputHeight < 0) {
Log.w("EmotionInputDetector", "Warning: value of softInputHeight is below zero!");
}
if (softInputHeight > 0) {
sp.edit().putInt(SHARE_PREFERENCE_TAG, softInputHeight).apply();
}
return softInputHeight;
}
这里的原理是通过当前Activity获取RootView的高度减去Activity自身的高度,就得到了软键盘的高度,但是发现在有虚拟按键的手机上在没有显示软键盘时减出来的高度总是144,后来查了下资料,发现在API>18时有软键盘的手机需要减去底部虚拟按键的高度。
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private int getSoftButtonsBarHeight() {
DisplayMetrics metrics = new DisplayMetrics();
mActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight) {
return realHeight - usableHeight;
} else {
return 0;
}
}
把获取到的高度设置给表情键盘
private void showEmotionLayout() {
int softInputHeight = getSupportSoftInputHeight();
if (softInputHeight == 0) {
softInputHeight = sp.getInt(SHARE_PREFERENCE_TAG, 400);
}
hideSoftInput();
mEmotionLayout.getLayoutParams().height = softInputHeight;
mEmotionLayout.setVisibility(View.VISIBLE);
}
控制表情的显示与隐藏
private void showSoftInput() {
mEditText.requestFocus();
mEditText.post(new Runnable() {
@Override
public void run() {
mInputManager.showSoftInput(mEditText, 0);
}
});
}
private