ConstraintLayout aspect ratio
Asked Answered
G

3

105

Consider the following layout file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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.support.constraint.ConstraintLayout
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FF0000"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin">

        <ImageView
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="#0000FF"
            android:padding="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintDimensionRatio="H,3:1"
            tools:layout_editor_absoluteX="16dp" />

    </android.support.constraint.ConstraintLayout>

</RelativeLayout>

I am not sure how the app:layout_constraintDimensionRatio works. My understanding is the ratio will always be width:height. So 3:1 will always make the ImageView appear 3 times wider than height. The prefix H or W tells ConstraintLayout which dimension should respect the ratio. If it is H then it means width will be first computed from other constraints and then height will be adjusted according to the aspect ratio. However this is the result of the layout:

enter image description here

The height is 3 times larger than width which is unexpected. Can anyone explain to me how the dimensions are computed with respect to app:layout_constraintDimensionRatio setting?

Garganey answered 21/12, 2016 at 14:50 Comment(0)
P
174

Your understanding for the way app:layout_constraintDimensionRatio works is correct. If you set app:layout_constraintDimensionRatio="H,3:1" then it means width will be first computed from other constraints and then height will be adjusted according to the aspect ratio. The only problem with your implementation is that you added app:layout_constraintBottom_toBottomOf="parent" to the ImageView, so that it caused app:layout_constraintDimensionRatio to be ignored.

Here's the layout to size your ImageView in 3:1 aspect ratio:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FF0000">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:background="#0000FF"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintDimensionRatio="H,3:1" />

</android.support.constraint.ConstraintLayout>

and here's the result view:

ImageView in 3:1 aspect ratio

Protero answered 11/9, 2017 at 16:5 Comment(2)
With androidx it's a androidx.constraintlayout.widget.ConstraintLayoutTater
Thanks. Now app:layout_constraintBottom_toBottomOf="parent" not affect to aspect ratio.Sessler
H
26

Basically, we have

layout_constraintDimensionRatio(width:height)

EXAMPLE

<!-- button which have width = it's content and height = 1/2 width -->
<Button
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent" <!-- I still think that we don't need this attribute but I when I don't add this, constraint not working -->
        android:text="Button TEST RATIO 1"
        app:layout_constraintDimensionRatio="2:1" />

Output
enter image description here

<!-- button which have width = it's content and height = 1/2 width -->
<Button
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        android:text="Button TEST RATIO 2"
        app:layout_constraintDimensionRatio="2" /> <!-- 2 here <=> 2:1 <=> 2/1 (1:1 <=> 1, 1/2 <=> 0.5, ....) ->

Output
enter image description here

<!-- button which have width = match_parent and height = 1/2 width -->
<Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:text="Button TEST RATIO 3"
        app:layout_constraintDimensionRatio="2" />

Output
enter image description here

<!-- button which have width = match constraint and height = 1/2 width -->
<Button
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Button TEST RATIO 4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintDimensionRatio="2" />

Output
enter image description here

DEMO: https://github.com/PhanVanLinh/AndroidConstraintLayoutRatio

Humiliating answered 10/7, 2018 at 6:52 Comment(0)
C
7

Take a look at these ImageView properties:

    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"

These properties override the layout_constraintDimensionRatio due to which the ImageView is constrained to the bottom, top and left of the main parent resulting in the View occupying the left, top and bottom portions of the main screen.

    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"

This would be one solution. You can omit layout_constraintBottom_toBottomOf if you want the View to appear on the top or vice-versa. It would probably be best to remove all the above constraints altogether except the layout_constraintDimensionRatio, which would be the most recommended solution.

Carious answered 21/12, 2016 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.