关于解决键盘闪动冲突的一点感想
2018-01-10 本文已影响173人
From64KB
项目最近需要加一个类似朋友圈的功能,这样就会涉及到需要发布动态。由于使用了自定义的Emoji,所以必须额外提供一个选择emoji的控件,如下图所示。
image.png这下加完问题来了,在上面一个EditText编辑文字想发Emoji的时候,布局就会闪动一下。选完emoji回到编辑状态的时候又会闪动一下。非常影响使用感受。
网上搜了搜,发现了一个非常好的解决方案:https://github.com/Jacksgong/JKeyboardPanelSwitch,不愧是大神在微信搞的方案,确实非常好用。但是问题是需要引入这个方案提供的其他组件,对于已经搞起来的项目多少有点麻烦。下面提供一下我的解决方案,没有上面提到这个项目那么全面和严谨,经过Pixel和三星等手机测试也能正常工作,解决了闪动问题。核心思想是在键盘弹出之前把Emoji选择控件gone掉,在键盘消失之后再显示emoji控件。具体做法如下:
- 首先将Activity的windowSoftInputMode设为adjustResize。
- 监听键盘的弹出和消失事件,使用下面这个类完成事件监听。
public class SoftKeyBoardListener {
private View rootView;//activity的根视图
int rootViewVisibleHeight;//纪录根视图的显示高度
private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;
public SoftKeyBoardListener(Activity activity) {
//获取activity的根视图
rootView = activity.getWindow().getDecorView();
//监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//获取当前根视图在屏幕上显示的大小
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int visibleHeight = r.height();
System.out.println(""+visibleHeight);
if (rootViewVisibleHeight == 0) {
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变
if (rootViewVisibleHeight == visibleHeight) {
return;
}
//根视图显示高度变小超过200,可以看作软键盘显示了
if (rootViewVisibleHeight - visibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度变大超过200,可以看作软键盘隐藏了
if (visibleHeight - rootViewVisibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
}
});
}
private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
}
public interface OnSoftKeyBoardChangeListener {
void keyBoardShow(int height);
void keyBoardHide(int height);
}
public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity);
softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener);
}
}
SoftKeyBoardListener.setListener(getActivity(), new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
@Override
public void keyBoardShow(int height) {
mShowKeyboard = true;
}
@Override
public void keyBoardHide(int height) {
mShowKeyboard = false;
if (mShowEmoji) {
if (mRLEmoji != null) {
mRLEmoji.setVisibility(View.VISIBLE);
}
}
}
});
这样就能完成事件监听。这样只是完成了键盘消失之后显示Emoji控件,但是还没有解决在键盘弹出之前Gone掉Emoji控件。具体做法是给上面的编辑框(EditText)设置点击事件,在点击事件中判断Emoji控件是否显示,如果显示就Gone掉。
这样就能解决掉键盘让布局闪动冲突的问题,但是这个方案比起https://github.com/Jacksgong/JKeyboardPanelSwitch,确实差了好多,没法实现更多的效果,也没有在其他布局或者是否全屏状态做过测试。希望可以帮到大家。