Reputation: 679
I want to create a compound view that contains 3 views in horizontal position. When I set the width of this compound view to WRAP_CONTENT, I want all those 3 views locate side by side as it is WRAP_CONTENT. But when I set the width to MATCH_PARENT, I want the second view to take over the whole space of the screen (but still second view located beside the first view).
Example:
WRAP_CONTENT:
|view1 view2 view3 --empty-space--|
MATCH_PARENT:
|view1 view2 --empty-space-- view3|
Due to some reason, I have to use constraint layout here.
I have tried the code below. When I tried to change the width of second view to WRAP_CONTENT, and set the whole constraint layout to MATCH_PARENT, the second view become located in the center (while what I want is to keep the location on the left)
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="view1"/>
<TextView
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/test1"
app:layout_constraintEnd_toStartOf="@id/test3"
android:text="view2"/>
<TextView
android:id="@+id/view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="view3"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Thank you. I appreciate any solutions.
Upvotes: 2
Views: 2399
Reputation: 908
add this to the A view
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
and set B to be a dependent of A:
ex:
<TextView
android:id="@+id/tv_description"
android:layout_width="0dp"
...
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintEnd_toStartOf="@+id/btn_allow_permission"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_permission_title" />
<Button
app:layout_constraintStart_toEndOf="@+id/tv_description"
...
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Upvotes: 0
Reputation: 27256
I'm not 100% sure I understand what you're trying to accomplish, but I'll extend (already given answers) for each case I can imagine:
| V1 | V2 | V3 ...... |
you simply need to tell the 3rd view to match_constraints
with android:layout_width="0dp"
and it will occupy all the space left by the other views (which have wrap).
This would produce the same output I understand from here:
|view1 view2 view3 --empty-space--|
Unless by -- empty space --
you meant |V1|V2|V3| ..... |
in which case you'd need a Constraint Layout Chain
and bias
:
On the left-most view, add:
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
and ensure all views have a connection between them, like view1 (left most) would have: startToStart=parent, endToStart=view2. View2 would then have startToEnd=view1, endToStart=view3, and view3... startToEnd=view2, endToEnd=parent
You get the idea.
This would pack all views to the start
leaving empty space at the end. The above would work regardless of the parent's constrains (match/wrap) since the engine will position/size views based upon the available space anyway.
Now, for your MATCH_PARENT example:
|view1 view2 --empty-space-- view3|
It's unclear (to me) what you mean by --empty space--, does this mean you want the view2
to wrap its contents? or do you want view2 to use all the available space and push view3 to the end?
I'll assume you mean all views are wrapping and there's empty space. There's a good answer about how to achieve that (hint, you'd need to chain in a space in between) if you don't know the exact dimensions, because the engine would have no way to determine how much space each view will consume before calculating the sizes and wrapping them.
Now, if you don't mind view2 taking all the remaining space and breaking the chain (only when needed), you can do the normal biased chain, but use a default spread condition for wrapping:
And so it would look like 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">
<TextView
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/view2"
app:layout_constraintTop_toTopOf="parent"
android:text="view1"/>
<TextView
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/view1"
app:layout_constraintEnd_toStartOf="@id/view3"
app:layout_constraintWidth_default="spread"
android:text="view2"/>
<TextView
android:id="@+id/view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/view2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
android:text="view3"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And this would produce something like:
| V1 | V2.............|V3|
Which may or may not work for you.
Upvotes: 3
Reputation: 6346
Put your Views
in a packed horizontal chain with a bias of 0
to align them to the left.
Packed chain will group the Views
side by side in the middle of the parent ConstraintLayout
. When none of your Views
has width set to 0dp
(match constraint) then you can control the horizontal positioning of this group by setting the bias. If you set your second View
to 0dp
then it will take all remaining space.
You can read more about chains in the documentation.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/view2"
app:layout_constraintTop_toTopOf="parent"
android:text="view1"/>
<TextView
android:id="@+id/view2"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/view1"
app:layout_constraintEnd_toStartOf="@id/view3"
android:text="view2"/>
<TextView
android:id="@+id/view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/view2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="view3"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Edit:
There are two options I can think of.
First, while setting the width of your parent layout to wrap_content
you can also set the width of the second View
to wrap_content
.
Second option is to add a Space
between the second and third View
to fill the remaining space when the parent layout is set to match_constraint
or shrink when you set it to wrap_content
.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/view2"
app:layout_constraintTop_toTopOf="parent"
android:text="view1"/>
<TextView
android:id="@+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/view1"
app:layout_constraintEnd_toStartOf="@id/space"
android:text="view2"/>
<Space
android:id="@+id/space"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/view2"
app:layout_constraintEnd_toStartOf="@id/view3"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/space"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="view3"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Upvotes: 0
Reputation: 26
ConstraintLayout provides an ability to determine chains between child views. There are available packed, spread_inside & spread.
You can read about chaining here: https://constraintlayout.com/basics/create_chains.html
Upvotes: 0