Constraint layout packed chain + dimension ratio, incorrect height

Viewed 707

I have the following 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"
    android:padding="32dp">

    <android.support.constraint.Guideline
        android:id="@+id/icon_guide_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".2"/>

    <android.support.constraint.Guideline
        android:id="@+id/icon_guide_end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".8"/>

    <ImageView
        android:id="@+id/icon"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintWidth_max="600dp"
        app:layout_constraintVertical_chainStyle="packed"
        app:layout_constraintStart_toStartOf="@+id/icon_guide_start"
        app:layout_constraintEnd_toEndOf="@+id/icon_guide_end"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/message"
        app:layout_constraintDimensionRatio="H,1:1"
        tools:src="@drawable/ic_launcher_background"/>

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/icon"
        app:layout_constraintBottom_toTopOf="@+id/action"
        tools:text="Nothing to see here"/>

    <Button
        android:id="@+id/action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/message"
        app:layout_constraintBottom_toBottomOf="parent"
        tools:text="Reload"/>

</android.support.constraint.ConstraintLayout>

The icon should consume 60% of the screen up to 600dp and have an aspect ration of 1:1. Next (below it) I want to have a message and an action. When running this layout with constraint layout 1.0.2 The icon view's height is computed to 0. If I remove the chain style packed, then the icon is the right size, but the views are no longer centered on the screen. I could wrap these in a vertical LinearLayout and center that, but then I lose the ability of the message to be wider than the icon.

Is this a bug in the constraint layout library? Is there a way around this?

2 Answers

Your layout looks like it works with ConstraintLayout 1.1.0-beta3. At least it looks like this:

enter image description here

If this is what you are expecting then it is fixed in the later non-production version. See this documentation related to the beta3 release. It mentions a fix to a "ratio in chain" bug fix that may be this problem.

I spent some time playing around with your layout. I think you've found a set of constraints the system solves in an unexpected way. I couldn't find a way to work around your problem, though I hesitate to cry bug just yet.

Some interesting observations:

  • The layout "worked" for me if I removed the max width constraint
  • If I remove the aspect ratio constraint and change the chain style to spread, the bounds of the image view grow to consume all available height
  • If I remove the aspect ratio constraint and change the max width to 100dp, the bounds of the image view change to 100x0 (as opposed to 0x0)

This leads me to believe that the packed chain style and the H,1:1 aspect ratio are "fighting" with each other to determine the dimensions of your view. Assuming that packed means "make each view as short as possible", the system can successfully satisfy all constraints by setting the view's dimensions to 0x0.

Related