20

I have a ConstraintLayout inside a NestedScrollView. The ConstraintLayout contains a bunch of views but the last View can have a dynamic height to fill up the bottom space if there is any but it also needs to be a minimum height if there is not enough space.

For arguments sake, here is an example.

<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

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

        <View
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintHeight_min="1500dp"
            android:background="@color/red"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"  
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
 
    </android.support.constraint.ConstraintLayout>


</android.support.v4.widget.NestedScrollView>

As you can see I have put the ConstraintLayout version in but it doesn't work. Obviously the values are ridiculously large but this is just for testing.

If I don't set fillViewport="true" on the NestedScrollView then ConstraintLayout has a height of 0. When I do set the fillViewport, the ConstraintLayout does not scroll but just fills the screen.

How can I set the View so that it expands to the bottom of the ConstraintLayout which should be as big as the Viewport but if my View is not of the minHeight then we allow scrolling?

I am using version 1.0.2 of the ConstraintLayout library.

What I expect to see is the being all the way to the bottom of the parent but if that size is less than 1500dp then the view scrolls.

I have entered 1500dp like so android:layout_height="1500dp" and the view scrolls accordingly.

UPDATE 1

Seems to be once I put the layout within a FragmentViewPager. The app:layout_constraintHeight_min property isn't respected and it only matches the height of the viewport.

I also tried taking the NestedScrollView out of the fragment and putting the ViewPager inside it but again didn't work.

Zain
  • 37,492
  • 7
  • 60
  • 84
StuStirling
  • 15,601
  • 23
  • 93
  • 150

3 Answers3

35

Add this attribute to the view you'd like to have stretch:

app:layout_constraintHeight_default="spread"

I made a tiny app to demonstrate. No java logic to speak of, but here's the layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    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:fillViewport="true">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:background="#caf">

        <TextView
            android:id="@+id/one"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:gravity="center"
            android:text="hello world"
            android:background="#fff"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/two"/>

        <TextView
            android:id="@+id/two"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:gravity="center"
            android:text="hello world"
            android:background="#eee"
            app:layout_constraintTop_toBottomOf="@+id/one"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/three"/>

        <TextView
            android:id="@+id/three"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:gravity="center"
            android:text="hello world"
            android:background="#ddd"
            app:layout_constraintHeight_default="spread"
            app:layout_constraintHeight_min="300dp"
            app:layout_constraintTop_toBottomOf="@+id/two"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>

    </android.support.constraint.ConstraintLayout>

</android.support.v4.widget.NestedScrollView>

The bottom view stretches to fill the viewport when it is smaller than the remaining available space, and scrolling is impossible:

enter image description here

The bottom view maintains a fixed height when it is larger than the remaining available space, which makes scrolling possible:

enter image description here enter image description here

Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • Thanks for the thorough answer. I used your answer to debug why the contraint layout wasn't working and found that other views with different constraints didn't play nicely with it. I changed the way these other views were constrained and it started working. My next problem is why it's not working when I put it in my ViewPager... – StuStirling Dec 17 '17 at 19:50
  • 1
    Ok it seems to be the `ViewPager` thats causing the issue – StuStirling Dec 18 '17 at 21:30
4

I am using com.android.support.constraint:constraint-layout:1.0.2 and this works for me:

<android.support.v4.widget.NestedScrollView 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:orientation="vertical">

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

        <View
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@drawable/gradient"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_min="1500dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>

</android.support.v4.widget.NestedScrollView>
Mehmed
  • 2,880
  • 4
  • 41
  • 62
0

As the first thing is we have to specify the fixed height to each text view or used wrap content as another option.Secondary inside constraint layout the property app:layout_constraintHeight_default="spread" helps the last view to get the remaining complete space left and if no space left then automatically synced to scroll view.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 
    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:fillViewport="true">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#caf"
        android:padding="16dp">

        <TextView
            android:id="@+id/one"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:background="#fff"
            android:gravity="center"
            android:text="hello world"
            app:layout_constraintBottom_toTopOf="@+id/two"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/two"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:background="#eee"
            android:gravity="center"
            android:text="hello world"
            app:layout_constraintBottom_toTopOf="@+id/three"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/one" />

        <TextView
            android:id="@+id/three"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:background="#eee"
            android:gravity="center"
            android:text="hello world"
            app:layout_constraintBottom_toTopOf="@+id/four"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/two" />

        <TextView
            android:id="@+id/four"
            android:layout_width="0dp"
            anroid:layout_height="48dp"
            android:background="#eee"
            android:gravity="center"
            android:text="hello world"
            app:layout_constraintBottom_toTopOf="@+id/five"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/three" />

        <TextView
            android:id="@+id/five"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="#ddd"
            android:gravity="center"
            android:text="hello world"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHeight_default="spread"
            app:layout_constraintHeight_min="300dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/three" />

    </android.support.constraint.ConstraintLayout>

</android.support.v4.widget.NestedScrollView>
Robert Estivill
  • 12,369
  • 8
  • 43
  • 64
P.sharma
  • 79
  • 1
  • 6