Balizok
Balizok

Reputation: 1075

Make a ScrollView take all space available - Android

I have a ConstraintLayout in which I have an image at the top and an action bar at the bottom that should both stay fixed. I have a ScrollView between them, and I want it to take all the space available between the image at the top and the action bar at the bottom. However, I tried using height=wrap_content but then the ScrollView gets displayed on top of the other components, and I didn't find any way other than fixing a height attribute. Still, then it's not dynamic anymore and it doesn't go to the bottom even though there's space available.

How should I go about doing that? Thanks in advance, here's the code of my layout :

<?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:id="@+id/popup_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/popup_show_image"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        tools:src="@drawable/default_show_image"
        app:layout_constraintTop_toTopOf="parent"/>

    <ScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/popup_show_image"
        app:layout_constraintBottom_toTopOf="@id/popup_action_bar"
        android:padding="@dimen/default_margin">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <!-- ScrollView content -->

        </LinearLayout>

    </ScrollView>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:id="@+id/popup_action_bar"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

        <!-- Action bar icons -->

    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

Upvotes: 1

Views: 639

Answers (1)

cactustictacs
cactustictacs

Reputation: 19622

The layout inside the ScrollView needs to have a height of wrap_content, so it's sized to the contents (which can be bigger than the ScrollView "window", moving the contents layer up and down is what allows it to scroll).

Your ScrollView needs to have layout_height="0dp" so it uses the vertical constraints to determine its height, which will be sized so it fills the space between the two views you've constrained it to. This is the size of the "window" into the scrollable content. It should never be wrap_content because that defeats the purpose of having a smaller window into a larger content layer!

The parent ConstraintLayout (popup_layout) needs to have either a fixed height, or match_parent, so it actually creates that extra space for the ScrollView to live in - i.e. it needs to be taller than the image + the action bar. If you want to make it wrap_content, then the ScrollView needs to have a fixed height too, so that's taken into account when sizing the parent layout.

<?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:id="@+id/popup_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/popup_show_image"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintTop_toTopOf="parent"/>

    <ScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/popup_show_image"
        app:layout_constraintBottom_toTopOf="@id/popup_action_bar"
        android:padding="16dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:lines="100"
                android:textSize="100sp"
                android:text="bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla "
                />

        </LinearLayout>

    </ScrollView>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:id="@+id/popup_action_bar"
        android:background="#FFCC22"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

        <!-- Action bar icons -->

    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

You can use the Layout Inspector in Android Studio to see what your view hierarchy looks like while it's running, and make sure everything's where it should be and sized correctly:

The Layout Inspector showing the working layout, with the ScrollView and its content layer outlined

You can see the ScrollView window there, with the larger content layout slid up a bit behind it ("scrolled down")

Upvotes: 1

Related Questions