Restrict width in ConstraintLayout by another view

Marius picture Marius · Jun 7, 2017 · Viewed 9.7k times · Source

Is there a possibility (in ConstraintLayout) to let a view grow only as long as there is space for another view at his right?

The use case is to have a value and unit TextViews besides each other. The value TextView should be able to grow as long as there is space for the unit. If there is not enough space, the value should be cut.

ConstraintLayout

I've tried it with chains and some other things but can't get it done. The value doesn't stop growing and then the unit is not visible anymore. Here's the current code:

<TextView
    android:id="@+id/value"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:lines="1"
    app:layout_constraintBaseline_toBaselineOf="@+id/unit"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@id/unit"
    tools:text="12533939532" />

<TextView
    android:id="@+id/unit"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintLeft_toRightOf="@id/value"
    app:layout_constraintRight_toRightOf="parent"
    tools:text="km" />

Answer

Pavan picture Pavan · Jun 7, 2017

yes you can by using match_constraint (0dp) which equal to match_parent for other layout, so by using match_constraint we set weight for first view which will occupies all available space also add

app:layout_constraintWidth_default="wrap"

to apply default width behavior as wrap_content

here is code with change

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

        <TextView
            android:id="@+id/value"
            android:layout_width="0dp"
            app:layout_constraintWidth_default="wrap"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:lines="1"
            app:layout_constraintBaseline_toBaselineOf="@+id/unit"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintHorizontal_chainStyle="packed"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@id/unit"
            tools:text="12533939532" />

        <TextView
            android:id="@+id/unit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            app:layout_constraintLeft_toRightOf="@id/value"
            app:layout_constraintRight_toRightOf="parent"
            tools:text="km" />

    </android.support.constraint.ConstraintLayout>

got some explanation from site

Better view dimension controls

The new available behaviors when a dimension is set to 0dp (MATCH_CONSTRAINT). As before, both endpoints (left/right or top/bottom) need to be connected to targets.

layout_constraintWidth_default = spread (default, similar to the previous behavior) layout_constraintWidth_default = wrap layout_constraintHeight_default = spread layout_constraintHeight_default = wrap

Wrap provides a significant new behaviour, with the widget resizing as if wrap_content was used, but limited by the connected constraints. A widget will thus not grow beyond the endpoints.

http://tools.android.com/recent/constraintlayoutbeta5isnowavailable