如何为带自定义视图的AlertDialog添加底部分割线
AlertDialog按钮区顶部添加全屏分割线及RecyclerView滚动截断问题解决
问题描述
我想给AlertDialog的按钮区域顶部添加一条全屏分割线,和原生长列表AlertDialog的样式一致。为了全应用复用,我采用了自定义视图,但现在遇到两个问题:
- 自定义视图和按钮之间间距过大
- 在自定义视图内添加的分割线受父布局padding限制,无法铺满对话框宽度
另外,原生AlertDialog中带分割线的ListView已替换为推荐使用的RecyclerView,我希望通过Builder实现分割线效果——因为有时用正负按钮组合,有时只用单个按钮,在通用布局里自定义所有情况过于繁琐。
原自定义布局代码(使用MaterialAlertDialogBuilder)
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.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" style="@style/AppCompatAlertDialogTheme" android:padding="?dialogPreferredPadding" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/alert_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="to" android:textAppearance="@style/TFAlertDialogStyle" android:textColor="@color/black" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/alert_explanation" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/padding_small" android:text="@string/lorem" android:textColor="@color/black" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/alert_title" tools:visibility="visible" /> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/alert_options" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/padding_small" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/alert_explanation"> <!--此处放置各AlertDialog的选项--> <androidx.recyclerview.widget.RecyclerView android:id="@+id/alert_options_recycler" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> <View android:id="@+id/alertDivider" style="@style/Divider" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
补充问题
当RecyclerView内容较多需要滚动时,现有布局会导致RecyclerView最后部分被padding遮挡,无法滚动到底部。
解决方案
- 若RecyclerView无需滚动,常规自定义分割线的方案即可生效
- 若有滚动需求:
- 需将内容视图改为LinearLayout而非ConstraintLayout,避免列表最后项被截断
- 若RecyclerView下方还有其他视图,父布局仍需使用ConstraintLayout,否则分割线会随列表滚动消失
最终可用布局
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content"> <!--不要改成ConstraintLayout,只有LinearLayout能解决滚动截断问题--> <androidx.appcompat.widget.LinearLayoutCompat android:orientation="vertical" android:id="@+id/alert_content_view" style="@style/AppCompatAlertDialogTheme" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="?dialogPreferredPadding"> <TextView android:id="@+id/alert_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" android:textAppearance="@style/TFAlertDialogStyle" android:textColor="@color/black"/> <TextView android:id="@+id/alert_explanation" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/padding_small" android:text="@string/desc" android:textColor="@color/black" tools:visibility="visible" /> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/alert_options" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/padding_small"> <!--此处放置各AlertDialog的选项--> <androidx.recyclerview.widget.RecyclerView android:id="@+id/alert_options_recycler" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> <!--部分视图设为gone--> </androidx.appcompat.widget.LinearLayoutCompat> <View android:id="@+id/alertDivider" style="@style/Divider" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
内容的提问来源于stack exchange,提问作者Sarah Multitasker
相关产品推荐
相关产品推荐

