Android键盘遮挡Bottom Sheet Dialog Fragment布局问题求助
问题描述
Activity中嵌入的BottomSheetDialogFragment,在键盘弹出时布局虽已上移,但键盘候选条仍会遮挡布局底部区域(如保存按钮)。已尝试adjustResize、adjustPan等windowSoftInputMode配置,问题未解决。
现有代码实现
EmailBottomSheet类
public class EmailBottomSheet extends BottomSheetDialogFragment { Context context; LinearLayout linearLayout; EditText emailEditText; TextView invalidEmailTextView; Button saveEmailButton; public EmailBottomSheet() { } @Override public int getTheme() { return R.style.DialogStyle; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.bottom_sheet_email_layout, container, false); view.setBackgroundResource(R.drawable.top_corner_curve_16); linearLayout = view.findViewById(R.id.bottom_sheet_email_layout); emailEditText = view.findViewById(R.id.list_of_emails); saveEmailButton = view.findViewById(R.id.save_email_lst_btn); invalidEmailTextView = view.findViewById(R.id.error_email_text); BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(linearLayout); setTextToEditText(); bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); return view; } private void setTextToEditText() { // 自定义文本设置逻辑 } }
样式文件DialogStyle
<style name="DialogStyle" parent="Theme.Design.BottomSheetDialog"> <item name="android:windowBackground">@null</item> <item name="android:windowIsFloating">false</item> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowSoftInputMode">adjustResize|stateVisible</item> </style>
底部Sheet布局文件bottom_sheet_email_layout.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout android:id="@+id/email_coordinator" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:background="@color/transperent"> <LinearLayout android:id="@+id/bottom_sheet_email_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/top_corner_curve_16" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" android:orientation="vertical"> <View android:layout_width="64dp" android:layout_gravity="center" android:layout_height="@dimen/value_4" android:layout_marginTop="@dimen/value_10" android:layout_marginBottom="@dimen/value_10" android:background="#1A000000"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="@dimen/value_12" android:layout_marginBottom="@dimen/value_12" android:layout_marginStart="@dimen/value_16" android:layout_marginEnd="@dimen/value_16" android:fontFamily="@font/proximanova_semibold" android:text="@string/emails_list" android:textColor="@color/text_grey" android:textSize="20sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/value_24" android:layout_marginStart="@dimen/value_16" android:layout_marginEnd="@dimen/value_16" android:text="@string/these_recipients" android:textSize="17sp" android:textColor="@color/text_grey" android:fontFamily="@font/proximanova_regular" android:layout_gravity="start"/> <EditText android:id="@+id/list_of_emails" android:layout_width="match_parent" android:layout_height="92dp" android:layout_marginStart="@dimen/value_16" android:layout_marginEnd="@dimen/value_16" android:layout_marginTop="@dimen/value_8" android:background="@drawable/edit_email_grey_bg" android:fontFamily="@font/proximanova_regular" android:gravity="start|top" android:imeOptions="actionNext" android:inputType="textMultiLine" android:paddingLeft="@dimen/value_16" android:paddingTop="@dimen/value_13" android:paddingRight="@dimen/value_16" android:paddingBottom="@dimen/value_13" android:textColor="@color/text_grey" android:textSize="17sp" /> <TextView android:visibility="gone" android:id="@+id/error_email_text" android:layout_marginHorizontal="@dimen/value_16" android:layout_marginTop="@dimen/value_8" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Email list is invalid" android:textSize="13sp" android:fontFamily="@font/proximanova_regular" android:textColor="#df0028"/> <Button android:id="@+id/save_email_lst_btn" style="@style/BlackButtonStyle" android:layout_width="match_parent" android:layout_height="52dp" android:layout_gravity="center" android:layout_marginStart="@dimen/value_16" android:layout_marginTop="@dimen/value_40" android:layout_marginEnd="@dimen/value_16" android:layout_marginBottom="@dimen/value_16" android:fontFamily="@font/proximanova_semibold" android:gravity="center" android:text="@string/save" android:textAllCaps="false" android:textColor="@color/white" android:textSize="17sp" /> </LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
解决方案
方法1:调整输入模式与布局适配
候选条遮挡的核心原因是系统计算键盘高度未包含候选条区域,结合fitsSystemWindows属性冲突,按以下步骤修改:
- 更新样式文件的
windowSoftInputMode,并给BottomSheet根布局禁用fitsSystemWindows:
<style name="DialogStyle" parent="Theme.Design.BottomSheetDialog"> <item name="android:windowBackground">@null</item> <item name="android:windowIsFloating">false</item> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowSoftInputMode">adjustResize|stateVisible|adjustPan</item> </style>
修改布局中的LinearLayout:
<LinearLayout android:id="@+id/bottom_sheet_email_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/top_corner_curve_16" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" android:orientation="vertical" android:fitsSystemWindows="false">
- 在Fragment的
onViewCreated中强制刷新Dialog布局:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (getDialog() != null && getDialog().getWindow() != null) { getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); getDialog().getWindow().getDecorView().requestLayout(); } }
方法2:监听键盘高度动态调整BottomSheet高度
通过监听键盘显示/隐藏事件,获取包含候选条的实际键盘高度,动态设置BottomSheet最大高度:
- 实现键盘监听逻辑:
private void setupKeyboardListener() { final View decorView = getDialog().getWindow().getDecorView(); decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect rect = new Rect(); decorView.getWindowVisibleDisplayFrame(rect); int screenHeight = decorView.getRootView().getHeight(); int keyboardHeight = screenHeight - rect.bottom; BottomSheetBehavior behavior = BottomSheetBehavior.from(linearLayout); // 留出16dp安全边距,避免布局紧贴键盘 int maxHeight = screenHeight - keyboardHeight - getResources().getDimensionPixelOffset(R.dimen.value_16); behavior.setMaxHeight(maxHeight > 0 ? maxHeight : ViewGroup.LayoutParams.MATCH_PARENT); // 键盘弹出时强制BottomSheet保持展开状态 if (keyboardHeight > screenHeight * 0.15) { behavior.setState(BottomSheetBehavior.STATE_EXPANDED); } } }); }
- 在
onViewCreated中调用监听方法:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); setupKeyboardListener(); }
方法3:禁用输入法候选条(业务允许时)
若不需要输入候选提示,可直接让EditText隐藏候选栏:
<EditText android:id="@+id/list_of_emails" ... android:inputType="textMultiLine|textNoSuggestions" android:imeOptions="actionDone|flagNoExtractUi" />
内容的提问来源于stack exchange,提问作者Kabilan
相关产品推荐
相关产品推荐

