I'd like to add a divider to an alert dialog at the bottom, similar to the one it shows when there are long list views (see image).
However, I've added a customized view, because I want to be able to use a generic layout for all my AlertDialogs in the whole app. Now there is a very huge space between view and buttons. Additionally the listview, which used to have the divider (from the original AlertDialog view), is not available anymore and my layout has it's own recyclerview. (Because they are recommended nowadays.)
I tried adding a divider in my custom view, but this divider is bound to the padding of it's parent and therefore doesn't fill the whole dialog (and is still heavily spaced from the buttons).
So I'd basically like to access the area of the buttons in the alertdialog to add a divider at the top of this view. (Which then would be full width and below the padding of the custom view.) It would be great, if this was possible with the Builder, because I sometimes use positive and negative buttons and sometimes only negative or only positive and customizing all that in a generic layout as well would be a huge effort.
Here's my custom layout (with divider). I'm using the MaterialAlertDialogBuilder. Note: I could remove the padding at the bottom to remove the space, but then it looks smashed and the problem with the width of the divider still isn't fixed.
<?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">
<!--In here will be the options for every alert dialog-->
<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>
Edit 1: It should also work with the recyclerview being filled, so it has to scroll, where the current solutions let the recyclerview disappear in the padding. There's 1 1/2 items left, but I can't scroll any further. (Image is without marginTop on Divider, with margin it actually disappears as well)
Solution: If you don't have a scrolling recyclerview with many items, @shraddha patel s approach works just fine. However, if you have one, to avoid cutting off the last items, you need to use a LinearLayout instead of a ConstraintLayout for the contentview, as shown in this somewhat related bug report: https://github.com/material-components/material-components-android/issues/1336 However, if you have items below the recyclerview, the parent layout still needs to stay a constraint layout or the divider will disappear in scrolling lists. So the working solution for me now is:
<?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">
<!--Don't ever refactor that to constraint layout.
There's some weird magic making it work only with a 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">
<!--In here will be the options for every alert dialog-->
<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>
//Some views set to visibility = 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>
If you have to implement the above UI using the ConstraintLayout layout then you can use the below code,
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
style="@style/AppCompatAlertDialogTheme"
android:padding="?dialogPreferredPadding"
android:layout_width="match_parent"
android:id="@+id/csLayout"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/alert_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Title"
android:textColor="@color/black"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/alert_explanation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/desc"
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="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/alert_explanation">
<!--In here will be the options for every alert dialog-->
<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>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="@+id/csLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:background="@color/black" />
</androidx.constraintlayout.widget.ConstraintLayout>