Search code examples
androidandroid-constraintlayoutaspect-ratioconstraint-layout-chains

ConstraintLayout chain with fixed aspect ratio


I'm trying to build an activity with 3 imageViews according to the following layout:

   <------W------->         <------W-------->
^  +---------------+--------+---------------+
|  |               |        |               |
|  |               |        |               |
H  |       A       |   B    |      C        |
|  |               | (1:3)  |               |
|  |               |        |               |
v  +---------------+--------+---------------+
  • H should be 1/3 of the parent height
  • B has a fixed aspect ratio of 1:3
  • A and C should have the same width

I tried multiple solutions and could never find one that works. The last one uses :

  • a guideline set to 33% of the parent height
  • an horizontal chain between A, B and C
  • a fixed aspect ratio for B
  • A, B and C use match_constraint dimensions

While I would expect that the solver would make the desired layout instead it seems the chain defines a similar width to all views as seen in the screenshot.

I also tried using a LinearLayout but it doesn't seem possible to fix the aspect ratio of items inside one.

enter image description here

<?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"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_bright"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintDimensionRatio=""
        app:layout_constraintEnd_toStartOf="@+id/imageView2"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0"
        app:srcCompat="@mipmap/ic_launcher" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_bright"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintDimensionRatio="1:3"
        app:layout_constraintEnd_toStartOf="@+id/imageView3"
        app:layout_constraintStart_toEndOf="@+id/imageView1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0"
        app:srcCompat="@mipmap/ic_launcher" />

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_bright"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/imageView2"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0"
        app:srcCompat="@mipmap/ic_launcher" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.3333" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.6666666666" />

</android.support.constraint.ConstraintLayout>

Thanks a lot!


Solution

  • There are probably several approaches to doing what you ask. Here is one approach:

    enter image description here

    The key to this layout is to set up the center image first as defined in the XML. Once the center image is established, it becomes easier to define the left and right images.

    <android.support.constraint.ConstraintLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <ImageView
            android:id="@+id/imageViewLeft"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@+id/imageCenter"
            app:layout_constraintEnd_toStartOf="@+id/imageCenter"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/imageCenter"
            app:srcCompat="@color/colorPrimary" />
    
        <ImageView
            android:id="@+id/imageCenter"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="W,1:3"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_percent="0.33"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0"
            app:srcCompat="@color/colorAccent" />
    
        <ImageView
            android:id="@+id/imageViewRight"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@+id/imageCenter"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imageCenter"
            app:layout_constraintTop_toTopOf="@+id/imageCenter"
            app:srcCompat="@color/colorPrimary" />
    </android.support.constraint.ConstraintLayout>