Reputation: 8363
I'm currently trying to layout something that I originally thought should be pretty easy with ConstraintLayout but after attempting it, I've realized I have no idea how to achieve this.
The idea is simple, layout a dialog-like view using a ConstraintLayout with no nesting.
The xml for this is simple (see below). The issue arrises when I wanted to make this layout scale for longer text on the buttons. For instance the desired layout might look like:
I was ultimately unable to come up with a nice solution that can work with:
Here's my layout xml if anyone wants to play with it.
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="24dp"
tools:text="Some title"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="8dp"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam luctus neque quis nunc ornare varius."
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/negativeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
style="@style/Widget.AppCompat.Button.Borderless"
tools:text="Cancel"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/positiveButton"
app:layout_constraintTop_toBottomOf="@+id/body"/>
<Button
android:id="@+id/positiveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
tools:text="Ok"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="@+id/negativeButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/negativeButton"
app:layout_constraintBottom_toBottomOf="@+id/negativeButton"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Edit: Just to list some things I've tried (and failed):
layout_constraintWidth_percent
layout_constraintHorizontal_weight
Edit2: Just to add more info. I am trying to make this as generic as possible since I wanted to create a re-usable component. So it should just work with button text of any length and not just specific text. This is a good idea anyways since localization can often cause the button text to be longer or shorter.
Upvotes: 1
Views: 1885
Reputation: 54204
I do not believe this is possible with ConstraintLayout
. There is no mechanism that will let you have both buttons behave "intelligently" when they both grow too large.
That said, here's something you could do to get close. First, set up a packed horizontal chain with a bias of 1:
app:layout_constraintHorizontal_bias="1"
app:layout_constraintHorizontal_chainStyle="packed"
Then use these two attributes to control the width of both of your buttons:
android:layout_width="0dp"
app:layout_constraintWidth_default="wrap"
This will give what you asked for, but only as long as the second button does not grow wide enough to fill the screen (at which point it will consume all of the available space).
To work around that, you can either set a minimum width on the first button:
app:layout_constraintWidth_min="100dp"
Or set a maximum width on the second button:
app:layout_constraintWidth_max="200dp"
Upvotes: 1
Reputation: 402
You can use guidelines to aid in laying out buttons. You'll want to constrain the rightmost button to the right guideline and have that guideline set at about 0.90 and have the left button's constraint_start to startOf parent. Constrain the right of the left button to the start of the right button.
Adjust the margins on the guidelines to account for additional padding requirements.
<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"
xmlns:tools="http://schemas.android.com/tools"
android:padding="10dp">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_left_vertical"
android:layout_width="2dp"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.05" />
<Button android:id="@+id/leftButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toStartOf="@+id/rightButton"
app:layout_constraintStart_toEndOf="@id/guideline_left_vertical"
app:layout_constraintTop_toTopOf="parent"
tools:text="Some Teggggggfffffffffffeeeeext" />
<Button android:id="@+id/rightButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginStart="2dp"
tools:text="Helfffghhhhhhhhhhlo"
app:layout_constraintEnd_toStartOf="@+id/guideline_right_vertical"
app:layout_constraintStart_toEndOf="@+id/leftButton"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_right_vertical"
android:layout_width="2dp"
android:layout_marginStart="5dp"
android:layout_height="2dp"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.95" />
</androidx.constraintlayout.widget.ConstraintLayout>```
Upvotes: 0
Reputation: 105
easiest way is to add android:maxWidth="200dp"
to the button you want to restrict
Upvotes: 0