androidx Recycler View match constraint (0dp) with wrap content behaviour

Viewed 608

I have simple recycler view here, what I want is:

when list is short: stick the button below the recycler view

when list is long: stick the button bottom of screen yet recycler view is wrapping properly and able to scroll till bottom

<?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="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_user_address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="15dp"
        android:layout_marginEnd="20dp"
        app:layout_constraintBottom_toTopOf="@id/btn"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintVertical_bias="0.0"
        tools:itemCount="50"/>

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="20dp"
        android:text="example"
        android:background="#00ffff"
        android:gravity="center"
        android:orientation="horizontal"
        app:layout_constraintTop_toBottomOf="@id/rv_user_address"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

When is wrap_content:

<androidx.recyclerview.widget.RecyclerView
android:layout_height="wrap_content"
...

short-list can stick button below properly but button is off screen when list is long

When is constraint:0dp:

<androidx.recyclerview.widget.RecyclerView
android:layout_height="0dp"
...

long list is correct behavior but short-list not stick button below list

I am out of idea. Thanks for helping.

enter image description hereenter image description hereenter image description hereenter image description here

3 Answers

Just add this line:

app:layout_constrainedHeight="true"

to your Recyclerview as:

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_user_address"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="15dp"
        android:layout_marginEnd="20dp"
        app:layout_constrainedHeight="true"   <--  Add this line
        app:layout_constraintBottom_toTopOf="@id/btn"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintVertical_bias="0.0"
        tools:itemCount="50"/>

Try this out. First align button at the end of the layout then add app:layout_constrainedHeight="true" app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toTopOf="@id/btn" in our recycler view. This will make your recycler view to cover all the layout except the button which is at the bottom of the layout. Still if you don't anything you can ask me.

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools">

      <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_user_address"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="20dp"
    android:layout_marginTop="15dp"
    android:layout_marginEnd="20dp"
    android:layout_marginBottom="10dp"
    app:layout_constrainedHeight="true"
    app:layout_constraintBottom_toTopOf="@id/btn"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.0"
    app:layout_constraintVertical_chainStyle="packed"
    tools:itemCount="100" />

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="20dp"
        android:background="#00ffff"
        android:gravity="center"
        android:orientation="horizontal"
        android:text="example"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here

Change your constraint layout to linear layout. Add weight-sum to linear layout. give the desired weights to your recycler view and button.

    <?xml version="1.0" encoding="utf-8"?>
   <LinearLayout
    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="match_parent"
    android:orientation="vertical"
    android:weightSum="10">

   <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_user_address"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9" 
        ...
       />

    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        ...
        />
</LinearLayout>

Just make sure the sum of all weights does not exceed your weight-sum. In the current case. Recycler view will have 90% of parent, while 10% is used by button. Feel free to play around with these number to achieve the desired results.

Related