BottomSheet含EditText遇软键盘上移异常,需实现自适应调整
嗨,我来帮你解决这个BottomSheet和软键盘适配的头疼问题!你遇到的情况是软键盘弹出后,BottomSheet虽然贴在键盘上方,但顶部却跑出去屏幕外了,对吧?咱们一步步来调整:
1. 给布局加上BottomSheetBehavior的“身份标识”
你的当前布局是CoordinatorLayout套了个RelativeLayout,但CoordinatorLayout还不知道这个RelativeLayout是个BottomSheet,所以没法帮它调整大小。咱们给RelativeLayout加上Behavior属性,让CoordinatorLayout能管理它:
修改你的布局文件,给最外层的RelativeLayout加上app:layout_behavior="@string/bottom_sheet_behavior":
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 加上这行,告诉CoordinatorLayout这是个BottomSheet --> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/bottom_sheet_behavior"> <!-- 原来的toolbar、RecyclerView这些内容都保持不变 --> <include android:id="@+id/toolbar_layout" layout="@layout/partial_toolbar" /> <android.support.v7.widget.RecyclerView android:id="@+id/list_comments" android:layout_below="@+id/toolbar_layout" android:layout_width="match_parent" android:overScrollMode="always" android:layout_height="match_parent"/> <!-- 其他View代码不变 --> </RelativeLayout> </android.support.design.widget.CoordinatorLayout>
2. 在setupDialog里给BottomSheet设置自适应规则
接下来要在Fragment的setupDialog方法里,配置BottomSheetBehavior的属性,让它知道要自适应内容高度,同时监听软键盘的变化:
@Override public void setupDialog(Dialog dialog, int style) { super.setupDialog(dialog, style); View contentView = View.inflate(getContext(), R.layout.your_bottom_sheet_layout, null); dialog.setContentView(contentView); // 获取BottomSheet的Behavior实例 CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams(); BottomSheetBehavior behavior = (BottomSheetBehavior) params.getBehavior(); if (behavior != null) { // 关键:让BottomSheet高度自适应内容,不会超出屏幕 behavior.setFitToContents(true); // 可选:如果需要监听BottomSheet的状态变化,可以加个回调 behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { // 比如处理展开/收起状态 } @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { // 处理滑动中的状态 } }); } // 确保软键盘弹出时窗口调整大小,这个你已经加了,再确认下 dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); }
3. 调整RecyclerView的高度避免被截断
你现在RecyclerView的高度是match_parent,当BottomSheet被压缩时,RecyclerView可能会超出可视范围。建议把它改成wrap_content,这样它会根据内容自动调整高度:
<android.support.v7.widget.RecyclerView android:id="@+id/list_comments" android:layout_below="@+id/toolbar_layout" android:layout_width="match_parent" android:overScrollMode="always" android:layout_height="wrap_content"/>
如果改成wrap_content后滚动有问题,也可以在代码里监听BottomSheet的高度变化,动态设置RecyclerView的最大高度。
4. 检查Activity配置的小细节
你已经在Manifest里给Activity加了android:windowSoftInputMode="adjustResize",这个是对的,但要注意:如果你的Activity主题设置了android:windowFullscreen="true",adjustResize会失效哦!如果有这个配置,记得移除它。另外,android:windowTranslucentNavigation也可能影响适配效果,要是上面的步骤都没解决,可以试试暂时注释掉这个属性看看。
最后再排查个小坑
确保你的Design Support Library(或者AndroidX对应的Material库)是最新版本,旧版本里BottomSheet和软键盘的交互可能存在bug,更新到最新版本大概率能解决一些奇怪的问题。
这样调整后,软键盘弹出时,BottomSheet应该会自动调整高度,既贴在键盘上方,顶部也不会超出屏幕啦!
内容的提问来源于stack exchange,提问作者waldemar

