Scrollview inside constraint layout does not scroll to the bottom of the parent constraint
Asked Answered
M

16

53

I have a form which has around 12/13 fields. I used a Scrollview inside a constraint layout. Below is the hierarchy of the XML layout. The problem is, it doesn't scroll to the bottom instead scrolls only to the first initial 10 views. The last 3 fields gets hidden as the view does not scroll any further.

PARENT LAYOUT

<android.support.constraint.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/activity_register"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical">

<!-- Textview and a button -->

  <ScrollView
    android:id="@+id/scrollView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:orientation="vertical"
    android:overScrollMode="never"
    android:scrollbars="none"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/view"
    tools:layout_constraintBottom_creator="1"
    tools:layout_constraintLeft_creator="1"
    tools:layout_constraintRight_creator="1"
    tools:layout_constraintTop_creator="1"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="0dp">


  <android.support.constraint.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

                <!-- Child Views (12/13 views of the fields)-->

  </android.support.constraint.ConstraintLayout>

</ScrollView>

</android.support.constraint.ConstraintLayout>
Mcphee answered 25/2, 2017 at 7:43 Comment(8)
Try to change android:layout_height parameter of ScrollView to match_parent.Stethoscope
Tried, yet it doesn't work.Mcphee
set height to match parent and fillViewPort true for your scrollview,Or try nested SCrollviewChancroid
which version of ConstraintLayout are you using? Could you post the full xml layout?Galsworthy
compile 'com.android.support.constraint:constraint-layout:1.0.0'Mcphee
could you provide the full layout ? (i.e. with the fields)Galsworthy
Hey did you find a solution for it? I am facing the same issue.Moxley
Looks to me as if you have a constraint layout inside a scrollview, not the other way around.Brockman
M
122

This layout works in my app. The trick is to set these two attributes in ScrollView: android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent"

The simplified layout from my app:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    android:theme="@style/ThemeOverlay.AppCompat.Light">

    <RelativeLayout
        android:id="@+id/linear"
        android:layout_width="0dp"
        android:layout_height="56dp"
        android:background="@color/title"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/linear">

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

            <TextView
                android:id="@+id/titleView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:layout_marginStart="8dp"
                android:text="@string/title"
                android:textSize="14sp"
                app:layout_constraintBaseline_toBaselineOf="@+id/title"
                app:layout_constraintLeft_toLeftOf="parent" />

            <EditText
                android:id="@+id/title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginEnd="8dp"
                android:layout_marginRight="8dp"
                android:hint="toilet title"
                android:inputType="text"
                android:textColor="@android:color/holo_red_dark"
                android:textSize="12sp"
                app:layout_constraintLeft_toLeftOf="@+id/open_hour"
                app:layout_constraintLeft_toRightOf="@+id/titleView"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
            ...
            Other Views in ScrollView
            ...
        </android.support.constraint.ConstraintLayout>
    </ScrollView>
</android.support.constraint.ConstraintLayout>
Millrun answered 30/6, 2017 at 9:56 Comment(4)
This works, but any reason to why 0dp works instead of wrap_content or match_parent?Braziel
In my case app:layout_constraintBottom_toBottomOf="parent" added to ScrollView works. great . I googled for many times until I found this solution. Thanks.Hooknose
Remember that the OUTER contraintlayout usually should have android:layout_width="match_parent", android:layout_height="match_parent". Otherwise the scrollview won't be visible with android:layout_height="0dp"Lobotomy
I have tried many examples both using "match_parent" and "wrap_content" neither work, use "0dp" it worksSicanian
D
19

In my case NestedScrollView worked instead of ScrollView. Following is the snippet of my working layout:

<android.support.constraint.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">

    <!-- Some Views Here -->

    <android.support.v4.widget.NestedScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:fillViewport="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view">

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

            <!-- Some Views That can be Scrolled Here -->

        </android.support.constraint.ConstraintLayout>

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

</android.support.constraint.ConstraintLayout>
Doubling answered 12/12, 2017 at 12:9 Comment(1)
Also add android:windowSoftInputMode="stateAlwaysHidden|adjustResize" in Manifest file Activity.Decoder
S
18

You have two solutions for this problem (the same solution but in two ways to do it):

  1. If you put the Design mode in Android Studio, select your ScrollView and open attributes tab and in the layout_height, select "match_constraint".

  2. If you use the Text mode in Android Studio, use this:

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toBottomOf="@id/tb_details">
    

See that the ScrollView height is set to 0dp. Both of this ways resolve the same problem but these are the different ways to do it.

The ScrollView is not the root view, I have a Constraint layout wrapping the ScrollView as you.

Saladin answered 9/5, 2018 at 17:22 Comment(1)
This worked. I have a ConstraintLayout with a child ScrollView that has a child LinearLayout that I populate with rows dynamically. The key in this solution is that the height (the axis of scrolling) has to be set to 0 AND the ScrollView must be constrained on both sides of the scrolling axis (top and bottom constraints in this case. If you have a horizontally scrolling view you need to set width to 0 and set start and end constraints)Deandra
L
13

Two Steps

  1. Keep layout height for scroll view zero
    android:layout_height="0dp"

  2. Again for scroll view
    android:fillViewport="true"

Lusty answered 30/10, 2017 at 13:3 Comment(1)
I my case both height and width needed to be 0dp, scrolling side needed to be match_parent, otherwise scroll did not worked. And of course all 4 constraints should be added to RecyclerViewHaight
I
10

Try adding bottom constraint to scrollview (eg: app:layout_constraintBottom_toBottomOf="parent") and change android:layout_height="wrap_content" to android:layout_height="0dp"

Isadoraisadore answered 8/12, 2017 at 10:45 Comment(1)
I forgot bottom constraint to scrollview. thank you so much :DImponderabilia
C
7

In my case NestedScrollView worked instead of ScrollView.

Following is the snippet of my working layout: Please make sure that you haven't make any childview height to match parent(0 dp) inside constrianlayout also for scroll view android:fillViewport="true;

Ask me if any doubt Occur.

<android.support.v4.widget.NestedScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="@dimen/_90sdp"
        android:fillViewport="true">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:id="@+id/cvLayout"
            android:animateLayoutChanges="true">
Camphene answered 5/7, 2018 at 10:7 Comment(1)
In my case ScrollView was not working but NestedScrollView is working fine..Hefty
D
4

Just Put android:fillViewport="true" in Parent Layout

Dorelle answered 24/8, 2018 at 6:15 Comment(0)
C
1

In my case, I had a tall TextView (height set to wrap_content) inside a ScrollView (height set to 0dp and being constraint on the top and bottom). No suggestions worked, but I solved the problem by wrapping the TextView inside a FrameLayout (height set to wrap_content).

Capeskin answered 22/11, 2018 at 10:39 Comment(0)
A
1

Never keep 0dp height of childs of ConstraintLayout if it is inside SV/NestedSV

wrap_content works because in this case ScrollView knows its childens height.

Ablaut answered 12/2, 2021 at 11:17 Comment(1)
THIS!!!! NEVER MAKE CONSTRAINTLAYOUT 0DP!!!! THANK YOUMetronymic
F
0

For me, I needed to add a LinearLayout inside my ScrollView in order to constrain it

<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">


    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="1dp">

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

            <View....</View>

        </LinearLayout>

    </ScrollView>


</androidx.constraintlayout.widget.ConstraintLayout>
Friedrick answered 26/12, 2019 at 14:27 Comment(0)
F
0

I have resolve this issue. Inside ScrollView you can not use constraint Layout. for using constrain inside scroll u have to use Relative layout is parent of constraint Layout..

so ur sequence should be:

ScrollView ---> Relative Layout ---> Constraint Layout

Fingering answered 4/5, 2020 at 12:47 Comment(0)
P
0

If you came here after searching "Soft Keyboard Hides the View elements"! Then you just have to add a scrollView and the same layout element again.
Before

<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">

   <ImageView
       android:id="@+id/imageView3"
       android:layout_width="246dp"
       android:layout_height="168dp"
       android:layout_marginTop="20dp"
       android:src="@drawable/img"/>
   <Button
       android:id="@+id/btn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>


After

<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">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                 android:id="@+id/imageView3"
                 android:layout_width="246dp"
                 android:layout_height="168dp"
                 android:layout_marginTop="20dp"
                 android:src="@drawable/img"/>
            <Button
                 android:id="@+id/btn"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"/>
        </androidx.constraintlayout.widget.ConstraintLayout>
 </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Pessa answered 9/12, 2020 at 19:4 Comment(0)
P
0

For the horizontal scroll view case (parent is ConstraintLayout, immediate child is LinearLayout), I found that setting the four constraints, layout_width=0dp, and fillViewport=true was not enough. It still didn't scroll.

What did work in my case was to set the four constraints and change the element from ScrollView to HorizontalScrollView. In that case layout_width can be set to "wrap_content" and fillViewport can be omitted. Additionally, I added a padding at the end of the immediate child of the HorizontalScrollView, to make the scrolling experience and the look better.

Plating answered 24/3, 2021 at 10:13 Comment(0)
A
0

I faced another issue where i had nestedscrollview which has constrainlayout which has linearlayout. This linearlayout has child get added programatically. So scroll was not working. Solved by replacing CL with LL with vertical orientation

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintTop_toBottomOf="@+id/separatr"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    android:fillViewport="true"
    android:fitsSystemWindows="true"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:orientation="vertical"
        tools:background="@color/yellow_highlight"
        android:paddingBottom="@dimen/box96">


        <TextView
            android:id="@+id/qansTv"
            style="@style/BodyText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/box200"
            android:layout_marginTop="@dimen/box32"
            android:layout_marginEnd="@dimen/box200"
            android:text="Lorem ipsum dofdfd fsd fdfsd sdf sdfsd fsdfsd fd sdfd fsdfsdf sdfsd df sdfd fsdfsd fsdf sdfsd dflors fdfdf."
            android:textColor="@color/white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <LinearLayout
            android:id="@+id/ansImageContainerLL"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:background="@color/red"
            android:layout_marginEnd="@dimen/box64"
            android:orientation="vertical"
            android:layout_marginStart="@dimen/box64"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/qansTv" />

    </LinearLayout>
</androidx.core.widget.NestedScrollView>
Ablaut answered 22/5, 2021 at 11:40 Comment(0)
A
0

in my case I had to use 2 recyclerviews and since it didn't want to scroll all the way I found a way to set to which length of the scrollview to scroll, the length is set by changing the width of the TextView.

<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView 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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.ProjectsFragment"
android:background="@color/blue">

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/scrollViewLength"
        android:layout_width="2000dp"
        android:layout_height="match_parent"
        android:text="Change the width above"
        android:visibility="invisible"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:tag="exampletag"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView1"
        android:tag="exampletag"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginTop="28dp"

        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
</FrameLayout>

</HorizontalScrollView>
Agnesse answered 23/10, 2021 at 21:50 Comment(0)
K
0

I know I'm late little bit ,I was facing the same issue what I did wrapped my RecyclerView Inside Linear or Relative layout and it worked like a charm,

Koester answered 25/1, 2022 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.