wang willway
wang willway

Reputation: 495

Why ConstraintLayout 1.1.0 layout_constraintWidth_percent and layout_constraintDimensionRatio cannot work together?

I am trying to use layout_constraintDimensionRatio and layout_constraintWidth_percent attribute together in an ImageView, but I find that they cannot be able to work together.

My xml code is:

1.using layout_constraintWidth_percent only:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        app:layout_constraintWidth_percent="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher"/>
</android.support.constraint.ConstraintLayout>

its corresponding UI is: layout_constraintWidth_percent_only.png

2.using layout_constraintWidth_percent and layout_constraintDimensionRatio:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintDimensionRatio="w,2:1"
        android:scaleType="fitXY"
        app:layout_constraintWidth_percent="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher"/>
</android.support.constraint.ConstraintLayout>

its corresponding UI is: layout_constraintWidth_percent_and_layout_constraintDimensionRatio.png

It's clear that when I use layout_constraintDimensionRatio, layout_constraintWidth_percent does not work.

What I really want is the width of the ImageView is 50% of its parent, and then the height of the ImageView is 50% of its width by using layout_constraintWidth_percent and layout_constraintDimensionRatio together.

Upvotes: 3

Views: 2337

Answers (1)

Pawel Laskowski
Pawel Laskowski

Reputation: 6316

Setting android:layout_height="0dp" to match constraint should help you achieve the desired result.

According to the documentation:

You can also use ratio if both dimensions are set to MATCH_CONSTRAINT (0dp). In this case the system sets the largest dimensions the satisfies all constraints and maintains the aspect ratio specified.

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        app:layout_constraintWidth_percent="0.5"
        app:layout_constraintDimensionRatio="2:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher"/>

</android.support.constraint.ConstraintLayout>

enter image description here

Edit It seems app:layout_constraintWidth_percent does not provide actual horizontal constraints by itself to the View so the following will behave differently (first on has the right horizontal constraint set and the second does not):

<ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        app:layout_constraintDimensionRatio="H,2:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.5"
        app:srcCompat="@mipmap/ic_launcher" />

and

<ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        app:layout_constraintDimensionRatio="H,2:1"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.5"
        app:srcCompat="@mipmap/ic_launcher" />

We are constraining the width based as percentage of the parent and then constraining the height based on width by using H in app:layout_constraintDimensionRatio="H,2:1". In the first case the view does not show and in the second it does in fact display correctly. It looks like if you want to use app:layout_constraintWidth_percent you need to add both horizontal constraints and then you can correctly constrain height based on width.

As the alternative to this approach you can use Guideline set at 50% of parent width to constrain your ImageView and then constrain height according to the ratio:

<?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"
    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="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        app:layout_constraintDimensionRatio="H,2:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/guideline"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_percent="0.5"
        app:srcCompat="@mipmap/ic_launcher" />

</android.support.constraint.ConstraintLayout>

Upvotes: 1

Related Questions