You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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属性冲突,按以下步骤修改:

  1. 更新样式文件的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">
  1. 在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最大高度:

  1. 实现键盘监听逻辑:
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);
            }
        }
    });
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:07:23