用recycleview实现了一个聊天的布局,但是在软键盘弹出的时候有些信息会被软键盘遮挡住.

解决方式1

在AndroidManifest里面配置当前的activity adjustPan 这个效果就是在你软键盘弹出的时候布局整体上移,虽然确实解决了我的问题,但是上面的titlebar也被上移了 ,体验很差。

1
android:windowSoftInputMode="stateHidden|adjustPan">

解决方式2

先配置activity adjustResize虽然还是会被遮挡但是titlebar就不会跟着软键盘而上移了

1
android:windowSoftInputMode="stateHidden|adjustResize">

键盘弹出的时候并没有相应的api给我们调用,但是可以通过另一种方式实现.我们就设置软键盘的模式是遮盖我们的布局的.那么键盘弹出必然导致我们的activity的根试图被覆盖,这时候会导致视图的重新调整,所以这时候我们只需要监听视图被重新安排了的回调,然后根据整个根布局的高度和可见的高度算出被遮盖的高度,也就是键盘的高度,然后,在让部分布局向上滚动一段距离,这段距离就是键盘的高度!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @param root 最外层布局
* @param needToScrollView 要滚动的布局,就是说在键盘弹出的时候,你需要试图滚动上去的View,在键盘隐藏的时候,他又会滚动到原来的位置的布局
*/
private void controlKeyboardLayout(final View root, final View needToScrollView) {
root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private Rect r = new Rect();
@Override
public void onGlobalLayout() {
//获取当前界面可视部分
ConversationAct.this.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
//获取屏幕的高度
int screenHeight = ConversationAct.this.getWindow().getDecorView().getRootView().getHeight();
//此处就是用来获取键盘的高度的, 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数
int heightDifference = screenHeight - r.bottom;
needToScrollView.scrollTo(0, heightDifference);
}
});
}

上面的scrollTo其实recycleview是用不了的 所以可以改成

1
((LinearLayoutManager) getRcView().getLayoutManager()).scrollToPositionWithOffset(getPresenter().getMessages().size() - 1, 0), 100);

但是这样会产生另一个问题就是你改变view比如下拉刷新这种就做不了,因为一致会定位到最后一个item

解决方法3

监听软键盘的弹起,然后在弹起后使用scrollToPositionWithOffset定位到最后一个位置

1
2
3
4
5
6
7
inputManager.setOnPopListener(() -> {
try {
Worker.postMain(() -> ((LinearLayoutManager) getRcView().getLayoutManager()).scrollToPositionWithOffset(getPresenter().getMessages().size() - 1, 0), 100);//这里的worker其实就是封装了下handler 延迟100秒主要就是为了在弹出后执行 不然无效
} catch (Exception e) {
e.printStackTrace();
}
});

资料