2

To make things simple, I have a ConstraintLayout with 2 childs: a RecyclerView and a Button.

I want the RecyclerView to start showing from the top of the parent. If there are only a few items to show in RecyclerView, it should wrap them. Something like this:

enter image description here

But, if the RecyclerView has enough items to go till the end of the screen, it should go instead till the top of the Button, not till the bottom of its parent. Like this: enter image description here

To achieve this effect I tried the following combination:

<android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/my_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />


        <android.support.v7.widget.RecyclerView
            android:id="@+id/my_recycler_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constrainedHeight="true"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

This solution was perfectly fine when the RecyclerView has only a few items to show. Otherwise, if it has to expand beyond the screen, it will go behind the Button.

After modifying the above xml to (note the line app:layout_constraintBottom_toTopOf="@id/my_button" at RecyclerView):

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/my_button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constrainedHeight="true"
        app:layout_constraintBottom_toTopOf="@id/my_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

The result I get is:

enter image description here

That is, the RecyclerView is positioning at the center between parent's top and button's top. This would be OK if the RecyclerView has many items, but not if there are only a small number of items.

Question: Is it possible to make my RecyclerView acting like:

  1. Regardless to the number of items, make its top positioning to be at the top of its parent.

  2. If there are few items, just wrap the content till the bottom of the last item.

  3. If there are many items, expand till the top of the Button, not till the bottom of the parent

?

P.S. The solution should be considered using as parent ConstraintLayout only.

Dionis Beqiraj
  • 737
  • 1
  • 8
  • 31

2 Answers2

8

You can use the app:layout_constraintHorizontal_bias attribute with a value of 0 to align your RecyclerView to its top constraint (1 would align to the bottom constraint). Both top and bottom constraints need to be set to use this bias. On the other hand, if the bottom constraint wasn't set then you wouldn't be able to prevent the RecyclerView from overlapping with the button. That's why it's important to set the bottom constraint and keep the app:layout_constrainedHeight="true" to make sure that the View's constraint are enforced when its height is set to wrap_content.

The top constraint of your RecyclerView is also incorrect as its top should be constained to the top of the parent and not the 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"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/my_recycler_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constrainedHeight="true"
            app:layout_constraintVertical_bias="0.0"
            app:layout_constraintBottom_toTopOf="@id/my_button"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/my_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Pawel Laskowski
  • 6,078
  • 1
  • 21
  • 35
  • "The top constraint of your `RecyclerView` is also incorrect as its top should be constained to the top of the parent and not the bottom." Sorry for that. It was a typing mistake of mine. Having this in mind, does it change anything in your solution? – Dionis Beqiraj Jun 24 '19 at 17:54
  • No, other than that I only added the `app:layout_constraintVertical_bias="0.0"` attribute to what you already had. – Pawel Laskowski Jun 24 '19 at 17:57
0
<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/my_button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/my_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
bmcglynn
  • 165
  • 1
  • 6