How to make view "wrap_content but not larger than" with ConstraintLayout?

4ntoine picture 4ntoine · May 21, 2017 · Viewed 17.5k times · Source

I'm having 3 view in a row: title, version and imageview (working as button):

  1. title should be wrap_content but respecting the following rules
  2. version should be wrap_content, to right of the title and to left of imageview
  3. imageview has fixed size and is at right top corner of the parent

enter image description here

The problem is if title is too large, the version is moved to right and rule "version is to the left of imageview" is not respected:

enter image description here

So i need to limit title width and make version visible and not moved to the right.

Here is XML:

<?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:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:background="#b3b2b2">

    <!--  -->
    <TextView
        android:id="@+id/LibraryWithVersionItem.title"
        android:layout_width="0dp"
        android:textStyle="bold"
        android:textSize="@dimen/fontSize18"
        android:textColor="@color/mySecondaryDarkColor"
        android:layout_height="wrap_content"
        android:ellipsize="middle"
        tools:text="ExampleLibrary 01234567890123456789012345"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        />

    <Spinner
        android:id="@+id/LibraryWithVersionItem.versions"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:textSize="@dimen/fontSize16"
        android:textColor="@color/mySecondaryDarkColor"
        tools:listitem="@layout/library_version"
        android:layout_marginTop="@dimen/margin8"
        android:layout_marginLeft="@dimen/margin8"
        android:layout_marginRight="@dimen/margin8"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/LibraryWithVersionItem.title"
        app:layout_constraintRight_toLeftOf="@+id/LibraryWithVersionItem.info"
        app:layout_constraintHorizontal_bias="0.0"/>

    <TextView
        android:id="@+id/LibraryWithVersionItem.sentence"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/LibraryWithVersionItem.title"
        tools:text="Some library description in one sentence\nbut two lines"
        android:layout_marginTop="@dimen/margin8"
        android:layout_marginLeft="@dimen/margin8"
        app:layout_constraintRight_toLeftOf="@+id/LibraryWithVersionItem.install"
        android:layout_marginRight="8dp"
        app:layout_constraintHorizontal_bias="0.0"/>

    <TextView
        android:id="@+id/LibraryWithVersionItem.isInstalled"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/LibraryManager.installed"
        android:textColor="#1a7c1a"
        android:layout_marginTop="@dimen/margin8"
        android:layout_marginBottom="@dimen/margin8"
        android:layout_marginLeft="@dimen/margin8"
        android:layout_marginRight="@dimen/margin8"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/LibraryWithVersionItem.sentence"
        app:layout_constraintRight_toLeftOf="@+id/LibraryWithVersionItem.install"
        app:layout_constraintHorizontal_bias="0.0"/>

    <!-- information button -->
    <ImageView
        android:id="@+id/LibraryWithVersionItem.info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/margin8"
        android:paddingLeft="@dimen/margin8"
        android:paddingRight="@dimen/margin8"
        android:paddingBottom="@dimen/margin8"
        android:scaleType="center"
        android:src="@drawable/ic_info_outline_white_24dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- install button -->
    <ImageView
        android:id="@+id/LibraryWithVersionItem.install"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/margin8"
        android:paddingRight="@dimen/margin8"
        android:paddingTop="@dimen/margin8"
        android:paddingBottom="@dimen/margin8"
        android:scaleType="center"
        android:src="@drawable/ic_get_app_white_24dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/LibraryWithVersionItem.info"/>


</android.support.constraint.ConstraintLayout>

PS 1. layout_width="0dp" + app:layout_constraintWidth_default="wrap" seems to be exactly what i need ("wrap_content but not breaking the constraints") but it does not work (still larger than required):

<TextView
        android:id="@+id/LibraryWithVersionItem.title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:ellipsize="middle"
        android:textColor="@color/mySecondaryDarkColor"
        android:textSize="@dimen/fontSize18"
        android:textStyle="bold"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="wrap"
        tools:text="ExampleLibrary 01234567890123456789012345"

PS 2. Setting min constraint width for the version (app:layout_constraintWidth_min="60dp") does not help too - it's invisible as it's moved too right.

Answer

4ntoine picture 4ntoine · May 21, 2017

Title and version should be in the chain and app:layout_constraintWidth_default="wrap" used:

<?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:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:background="#b3b2b2">

    <!-- information button -->
    <ImageView
        android:id="@+id/LibraryWithVersionItem.info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/margin8"
        android:paddingLeft="@dimen/margin8"
        android:paddingRight="@dimen/margin8"
        android:paddingBottom="@dimen/margin8"
        android:scaleType="center"
        android:src="@drawable/ic_info_outline_white_24dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <!--  -->
    <TextView
        android:id="@+id/LibraryWithVersionItem.title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:ellipsize="middle"
        android:textColor="@color/mySecondaryDarkColor"
        android:textSize="@dimen/fontSize18"
        android:textStyle="bold"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="wrap"
        tools:text="ExampleLibrary 01234567890123456789012345"
        app:layout_constraintRight_toLeftOf="@+id/LibraryWithVersionItem.versions"
        android:layout_marginRight="8dp"
        android:layout_marginLeft="8dp"
        android:paddingBottom="1dp"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintHorizontal_bias="0.0"/>

    <Spinner
        android:id="@+id/LibraryWithVersionItem.versions"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="@dimen/fontSize16"
        android:textColor="@color/mySecondaryDarkColor"
        tools:listitem="@layout/library_version"
        app:layout_constraintRight_toLeftOf="@id/LibraryWithVersionItem.info"
        app:layout_constraintLeft_toRightOf="@+id/LibraryWithVersionItem.title"
        android:layout_marginRight="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/LibraryWithVersionItem.title"
        android:layout_marginBottom="0dp"/>

    <TextView
        android:id="@+id/LibraryWithVersionItem.sentence"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/LibraryWithVersionItem.title"
        tools:text="Some library description in one sentence\nbut two lines"
        android:layout_marginTop="5dp"
        android:layout_marginLeft="@dimen/margin8"
        app:layout_constraintRight_toLeftOf="@+id/LibraryWithVersionItem.install"
        android:layout_marginRight="8dp"
        app:layout_constraintHorizontal_bias="0.0"
        android:layout_marginStart="@dimen/margin8"
        android:layout_marginEnd="8dp"/>

    <TextView
        android:id="@+id/LibraryWithVersionItem.isInstalled"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/LibraryManager.installed"
        android:textColor="#1a7c1a"
        android:layout_marginTop="@dimen/margin8"
        android:layout_marginLeft="@dimen/margin8"
        android:layout_marginRight="@dimen/margin8"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/LibraryWithVersionItem.sentence"
        app:layout_constraintRight_toLeftOf="@+id/LibraryWithVersionItem.install"
        app:layout_constraintHorizontal_bias="0.0"
        android:layout_marginStart="@dimen/margin8"
        android:layout_marginEnd="@dimen/margin8"/>

    <!-- install button -->
    <ImageView
        android:id="@+id/LibraryWithVersionItem.install"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/margin8"
        android:paddingRight="@dimen/margin8"
        android:paddingTop="@dimen/margin8"
        android:paddingBottom="@dimen/margin8"
        android:scaleType="center"
        android:src="@drawable/ic_get_app_white_24dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/LibraryWithVersionItem.info"/>

</android.support.constraint.ConstraintLayout>

I've tried to align version to title baseline but if the title is 2 or more lines it's aligned to the first line and it's not desired. So i had to align version to title bottom and hardcode title -3 bottom padding.

enter image description here

enter image description here

However, it looks as desired in Android Studio:

enter image description here

but on hardware device it looks different:enter image description here

When analyzing in Layout Inspector i can see title width is calculated wrong:enter image description here

Probably it's side effect of using it in RecyclerView but anyway...