Can I use a ConstraintLayout
to create a view that aligns children views to based on the largest child view?
Example:
Taking into account that the right Text
printed can be larger in one of the rows, I'd like to have the progress bars be aligned to the largest Text
on the right.
Is that possible? I can do it with nested LinearLayout
but was wondering if ConstraintLayout
solves this
Create a Barrier
with start
direction and reference all the IDs of the TextViews
on the right. Constrain the end
of each progress bar to the Barrier
. The Barrier
will be aligned to the start of the longest TextView
.
Sample XML of how to achieve this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="text1,text2"/>
<TextView
android:id="@+id/progress1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ProgressBar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="@id/barrier" />
<TextView
android:id="@+id/progress2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ProgressBar"
app:layout_constraintTop_toBottomOf="@id/progress1"
app:layout_constraintEnd_toStartOf="@id/barrier" />
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Longer Text"
app:layout_constraintTop_toBottomOf="@id/text1"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
To prevent the left TextView
from overlapping with other Views
you need to constrain its end
to progress bar, set horizontal bias to 0
so that it's aligned to its start
constraint and also set app:layout_constrainedWidth="true"
to its constraints are enforced when the width is set to wrap_content
. It should look like this:
<TextView
android:id="@+id/foo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Foo"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/progress1"
app:layout_constraintTop_toTopOf="parent" />
It will cause the text to wrap to the next line when it reaches the progress bar. You can add ellipsis or limit the TextView
to have the maximum of 1 line if you don't want the text to wrap.
Alternatively, you can just set the left TextView's
width to 0
so it takes all available space to the left of the progress bar.