1

I have FrameLayout with ConstraintLayout inside it. ConstraintLayout has android:layout_height="wrap_content" attribute. FrameLayout has fixed size which is smaller than desired by ConstraintLayout. I expect that when I increase FrameLayout height at runtime, height of ConstraintLayout will also grow until it's content fit. But it does not happen. It works as expected if I switch to FrameLayout instead of ConstraintLayout or if I call requestLayout() directly on ConstraintLayout. What could be the reason of such behavior?

Layout:

 <FrameLayout
            android:id="@+id/view2"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginBottom="16dp"
            android:background="@drawable/frame_layout_bg">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/constraint_layout_bg">

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:gravity="top|center_horizontal"
                    android:padding="16dp"
                    android:text="Constraint layout content"
                    android:textSize="24sp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />
            </androidx.constraintlayout.widget.ConstraintLayout>
        </FrameLayout>

Change height code:

        val frameLayout = findViewById<ViewGroup>(res)

        val finalHeight = TypedValue
            .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100f, resources.displayMetrics)
            .toInt()

        val layoutParams = frameLayout.layoutParams
        layoutParams.height = finalHeight

        frameLayout.layoutParams = layoutParams
        frameLayout.requestLayout()

Created example project to demonstrate the issue

Mikhail
  • 309
  • 1
  • 6
  • Calling `requestLayout()` for parent layout not make remeasure of child layouts. You should call `child.forceLayout()` with `parent.requestLayout()` or as you said you should call directly `child.requestLayout()`. You can read [this](https://stackoverflow.com/questions/13856180/usage-of-forcelayout-requestlayout-and-invalidate) and [this](https://stackoverflow.com/questions/45383948/how-does-forcelayout-work-in-android) to get more information. – Sergey Melnik Jan 06 '21 at 15:02
  • Thank you for your reply and links. Interesting, and I can understand that. The thing I cannot understand is why after switching from ConstraintLayout to any other ViewGroup (FrameLayout, LinearLayout, GridLayout etc.) I have everything working correctly with single requestLayout() on parent layout? In my opinion, any ViewGroup should re-measure it's children after changing the size, because some of the children might want to have more space than they had before. At least ViewGroups which allow non-fixed size (constrained, stretched etc.) for their children – Mikhail Jan 06 '21 at 16:17

1 Answers1

0

This seems to be a bug in ConstraintLayout that started with the version 2.0.2, I just created a pull request suggesting a fix for this issue hope it will be fixed soon, you can just switch back to 2.0.1 to avoid this issue till it gets resolved in future versions

Muhannad Fakhouri
  • 1,468
  • 11
  • 14