How to Put a Constraintlayout Inside a Scrollview

Is it possible to put a ConstraintLayout inside a ScrollView?

There was a bug with ConstraintLayout inside ScrollViews and it has been fixed. google has fixed the bug in Android Studio 2.2 Preview 2 (constraintlayout 1.0.0-alpha2).

Check this link for new update (Preview 2): works properly inside ScrollView and RecycleView

Solution 1:

The solution was to use android:fillViewport="true" on the
ScrollView

Solution 2:

Use NestedScrollView instead of ScrollView with android:fillViewport="true"

Edit - 09/16/20:

Currently, it is more usual to use the ScrollView with the ConstraintLayout height set to wrap_content, it works very well, don't forget the fillViewPort and that both Scroll and Nested support only one direct child.

ConstraintLayout inside a Scrollview - Problem

Finally found a solution, the guidelines were to blame as soon i removed them, everything started to work as expected, and i also changed the RecycleViews's height to wrap_content.

ScrollView not working inside constraint layout

You missed some constraint to give as you have added tools:ignore="MissingConstraints" in <ScrollView tag.

There are two ways:

  1. Remove Parent Constraint Layout and use RelativeLayout as no need of ConstraintLayout in just two layouts. (It is mostly used for complex view to make it easy)

  2. Give proper constraint if you want to use ConstraintLayout. You missed left, right, bottom constraint as follow:

    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:fillViewport="true"
    app:layout_constraintTop_toBottomOf="@id/other_toolbar_xml"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" >

    //....

    </ScrollView>

How to make a nested constraint layout inside scrollview to match the size of main parent layout

What you haven't mentioned is what is it doing now. You say you want to do something but it's a little unclear to me.

Are you referring to android:id="@+id/layout"?

If that's the case, then you're asking way too much here I believe.

Your hierarchy looks like this:

<CL> (ConstraintLayout)
<Toolbar>
<ScrollView>
<CL>
<CardView>
<CL>
<ImageView />
<TextView />
</CL>
</CardView>
<TextView />
<TextView />
<TextView />
<TextView />
<CL>
<Button>
<Button>
</CL>
</CL>
</ScrollView>
</CL>

My initial suggestion before you use any hacks (that you shouldn't like android:fillViewport) is to evaluate if your constraints are fulfilling all the possible directions and sizes.

That's quite a bit of calculation to perform by the ScrollView (which has to ask its children for their sizes). Something they can't possibly do as written, for some are "wrap" content, but don't have full constraints, meaning they have to wait and measure themselves before being able to tell "I need this amount of space". Now put all this in the measure/layout pass and imagine how long it can take and how painful it is for the engine.

ScrollViews aren't the best either, for all must be measured for the scrollview to draw its scrollable part (scrollbars, and content).

I think the missing bit here is maybe a vertical chain, but keep this in mind:

when you ask a widget to WRAP its content and you only provide ONE constrain, for e.g a TextView that is set to WRAP its height, but only has a "top_to_" constrain (but not a bottom_to...) then the widget doesn't have a known size nor a way to calculate it, until its text is measured (an expensive and slow operation) for you can have any arbitrary font size, padding, etc. A TextView is a simple example, ImagesViews are another similar, since the image source may now be known at compile time and until runtime.

The way to avoid most of these issues, is to correctly chain the widgets and have them wrap their contents when needed.

There's a app:layout_constraintHeight_default="wrap" property you can use to let the widget know it can break the constraints if needed.

I'd suggest you play around with it a little bit more for there's room to improvement in the way you're declaring your constraints.

implementing constraint layout in scrollview

Actually, your code should work when there is enough elements to scroll, try to add a higher margintop to the text view and you will see the result:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:gravity="center_horizontal"
tools:context=".MainActivity">

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

<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="630dp"
android:layout_marginBottom="32dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintGuide_percent="1.0"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="22dp"
android:layout_marginStart="8dp"
android:layout_marginTop="600dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="@id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />

</android.support.constraint.ConstraintLayout>
</ScrollView>

Android ConstraintLayout: extending inner Scrollview with respect to vertical neighbor-views

I think I got it down to what you're expecting now. Could you verify?

<?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"
android:theme="@style/Theme.AppCompat.Light">

<TextView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/shadeOfGrey2"
android:gravity="center"
android:text="header"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="@+id/addItem"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="packed">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:itemCount="8"
tools:listitem="@android:layout/simple_list_item_2" />

</androidx.core.widget.NestedScrollView>

<Button
android:id="@+id/addItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button 01"
app:layout_constraintBottom_toTopOf="@+id/footer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nestedScrollView"
app:layout_constraintVertical_bias="0" />

<TextView
android:id="@+id/footer"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@color/shadeOfGrey2"
android:gravity="center"
android:text="footer"
app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Just keep in mind that your approach above won't be recycling any views in the RecyclerView adapter, so if the data is big then performance might become a concern.

Screenshots from Android Studio:

0 items

3 items

8 items+



Related Topics



Leave a reply



Submit