继承AlertDialog实现自定义弹窗时底部出现大量空白的解决咨询
自定义AlertDialog底部多余空白问题解决
问题背景
为了实现带自定义视图和多种行为的弹窗,我选择继承AlertDialog而非使用Builder,核心代码和布局如下:
自定义Dialog代码
class MyTaskCreateDialog extends AlertDialog implements DialogInterface.OnCancelListener { public MyTaskCreateDialog(Context ctx, TaskItem item, List<Person> people, IOnFinishListener listener) { super(ctx); View view = LayoutInflater.from(ctx).inflate(R.layout.dialog_my_task_create, null, false); setView(view); setCancelable(true); setOnCancelListener(this); setCanceledOnTouchOutside(true); assign_views(view); // 将视图绑定到局部变量 attach_listeners(); refresh_view(); // 用数据更新视图 } }
对应的布局文件
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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="wrap_content" android:padding="@dimen/app_padding"> <android.support.design.widget.TextInputLayout android:id="@+id/my_task_create_title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/app_margin" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <android.support.design.widget.TextInputEditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/my_task_create_hint_title" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:id="@+id/my_task_create_description" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="8dp" app:layout_constraintEnd_toEndOf="@+id/my_task_create_title" app:layout_constraintStart_toStartOf="@+id/my_task_create_title" app:layout_constraintTop_toBottomOf="@+id/my_task_create_title"> <android.support.design.widget.TextInputEditText android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/my_task_create_hint_description" /> </android.support.design.widget.TextInputLayout> <TextView android:id="@+id/my_task_create_assignee_caption" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_task_create_caption_assignee" app:layout_constraintBottom_toBottomOf="@+id/my_task_create_assignee" app:layout_constraintStart_toStartOf="@+id/my_task_create_description" app:layout_constraintTop_toTopOf="@+id/my_task_create_assignee" /> <Spinner android:id="@+id/my_task_create_assignee" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/app_margin" android:checked="true" android:padding="@dimen/app_padding" android:textOff="@string/my_task_create_toggle_manually" android:textOn="@string/my_task_create_toggle_automatically" app:layout_constraintEnd_toEndOf="@+id/my_task_create_description" app:layout_constraintStart_toEndOf="@+id/my_task_create_assignee_caption" app:layout_constraintTop_toBottomOf="@+id/my_task_create_description" tools:listitem="@android:layout/simple_spinner_item" /> <Button android:id="@+id/my_task_create_create_task" style="@style/Widget.AppCompat.Button.Borderless.Colored" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/app_margin" android:text="@string/my_task_create_button_create" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/my_task_create_cancel" app:layout_constraintTop_toBottomOf="@+id/my_task_create_assignee" /> <Button android:id="@+id/my_task_create_cancel" style="@style/Widget.AppCompat.Button.Borderless.Colored" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/app_margin" android:text="@string/my_task_create_button_cancel" app:layout_constraintEnd_toStartOf="@+id/my_task_create_create_task" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/my_task_create_assignee" /> </android.support.constraint.ConstraintLayout>
运行后弹窗底部出现大量空白,将ConstraintLayout背景改为灰色后,确认空白区域是弹窗默认背景色——这是系统为默认按钮预留的空间,但我使用的是布局内的自定义按钮,请问如何消除这些多余空白?
解决方案
这个问题的核心是:AlertDialog的默认布局自带了一个按钮面板(即使你没设置任何按钮),这个面板会占据固定空间,导致底部出现多余空白。下面给你两种简单有效的解决方法:
方法一:使用带边距参数的setView重载方法
你当前调用的setView(view)会应用系统默认的内边距,同时保留按钮面板的占位。换成带四个边距参数的重载版本,把所有边距设为0,就能直接移除这些预留空间:
// 替换原来的setView(view) setView(view, 0, 0, 0, 0);
方法二:直接隐藏默认按钮面板
我们可以找到AlertDialog布局中默认的按钮面板(系统id为android.R.id.buttonPanel),然后将其设置为隐藏状态。你可以在构造函数末尾添加这段代码:
// 获取并隐藏默认按钮面板 View buttonPanel = findViewById(android.R.id.buttonPanel); if (buttonPanel != null) { buttonPanel.setVisibility(View.GONE); }
两种方法都能解决问题,个人更推荐方法二——它直接针对问题根源,逻辑更清晰,也不会影响自定义布局的内边距设置(你可以继续在布局里用android:padding控制内部间距)。
内容的提问来源于stack exchange,提问作者Cruces
相关产品推荐
相关产品推荐

