Reputation: 8701
I would like to have a horizontal LinearLayout
that is as wide as the screen and as high as its children, but the trick is that its children will have dynamic width each and I don't want them going off screen (cut out). I want them to flow/break in a new line so that they are all visible.
Although totally irrelevant to Android, it should work similar to how inline <div>
's work in HTML.
Here's what I have right now:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="If you would enter some digits in this field " />
<EditText
android:id="@+id/tvDistance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="enter some digits here"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" that would be great" />
</LinearLayout>
But as soon as the children of the LinearLayout
get wider than the screen the extra part gets off the screen/invisible.
Upvotes: 22
Views: 10746
Reputation: 5167
In addition to Flexbox you could use ChipGroup which is part of the Material Design Library
The ChipGroup
can be a container for other components as well, it doesn't have to be a Chip
, it could be a button etc.
A ChipGroup is used to hold multiple Chips. By default, the chips are reflowed across multiple lines. Set the app:singleLine attribute to constrain the chips to a single horizontal line. If you do so, you'll usually want to wrap this ChipGroup in a HorizontalScrollView.
<com.google.android.material.chip.ChipGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipText="This" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipText="is" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipText="a" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipText="because" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipText="chip" />
<com.google.android.material.chip.Chip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:chipText="group" />
</com.google.android.material.chip.ChipGroup>
Updated:
Starting with Constraint Layout 2.0
we can now use Flow
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:flow_wrapMode="chain"
app:constraint_referenced_ids="card1, card2, card3"
/>
Notice app:constraint_referenced_ids
and app:flow_wrapMode
First one is about passing the views and the second one about handling the way we wrap them.
Make sure to read about it on the official documentation
Upvotes: 10
Reputation: 87064
I would like to have a horizontal LinearLayout that is as wide as the screen and as high as its children, but the trick is that its children will have dynamic width each and I don't want them going off screen (cut out).
A LinearLayout
can't do that(any default layout from the SDK can't do that) because the LinearLayout
is set to place all the children in one horizontal or vertical line. Also, any type of conditional layout rules based on dimensions not yet available(like in your case the available width for the LinearLayout
) are not possible in the xml anyway.
What you need is a custom layout which measures the children to use the available space moving any non fitting children on a new line below(a so called FlowLayout
).
Edit:
Google now provides the flexbox
library which implements the web's flexbox layout on Android. Using that library, the children of a FlexboxLayout
will be placed on multiple lines based on their widths by using the flexDirection
(with a value of row) and flexWrap
(with a value of wrap) attributes.
Upvotes: 26