Reputation: 5579
I have two views within a LinearLayout
, both of which should wrap_content
such that they are minimally large enough to display their content. The LinearLayout
view group should wrap_content
of the two child groups such that it is just large enough to display the content of both child views.
But after this, if one of the two child views is larger, the other child view should expand to match parent to fill the remaining space available to it. The content of the two child views is dynamic and is unknown which will be larger at runtime.
The two child views are a TextView
and a Spinner
. The Spinner
should fill any remaining space in the LinearLayout
width. But if I change the Spinner
layout_width
to match_parent
and the TextView
is not large enough, the Spinner
will truncate its contents.
Basically I need a way to choose the maximum width between wrap_content
and match_parent
.
This is the layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parentView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:textSize="12sp"
android:textColor="?android:textColorHint"
tools:text="Label" />
<Spinner
android:id="@+id/spinner"
style="@style/Widget.AppCompat.Spinner.Underlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!-- or android:layout_width="match_parent"? need max of both... -->
</LinearLayout>
Upvotes: 7
Views: 6122
Reputation: 5579
Update: Ben P's answer accomplishes this while still using a LinearLayout
.
After further testing different solutions, turns out a better solution is to not use LinearLayout
as the parent view group. For whatever reason, a FrameLayout
provides the desired behavior of wrapping the child view's content, even when the child view is set to match_parent
, such that the max of the two sizes is used. LinearLayout
does not provide this same behavior.
But then the problem is how to get the two child views to stack vertically. This can be achieved in the FrameLayout
with a combination of layout_gravity
and a Space
view. For some odd reason, at least in my use case of using this layout as an item in a FlexboxLayout
parent, setting the FrameLayout
height explicitly won't work to size its height. Using wrap_content
with a Space
view set to the required height does work.
This is a layout that works, without requiring any additional code:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parentView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!-- setting FrameLayout layout_height doesn't work for some reason -->
<Space
android:layout_width="0dp"
android:layout_height="56dp" />
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:textSize="12sp"
android:textColor="?android:textColorHint"
tools:text="Label" />
<Spinner
android:id="@+id/spinner"
style="@style/Widget.AppCompat.Spinner.Underlined"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</FrameLayout>
Upvotes: 0
Reputation: 54194
There's a trick you can use to accomplish this with LinearLayout
and no extra views: use wrap_content
on the parent LinearLayout and match_parent
for both of the children. As long as the LinearLayout doesn't have any children with fixed sizes, this combination will make the overall parent as wide as its widest child.
<LinearLayout
android:layout_width="wrap_content"
...>
<TextView
android:layout_width="match_parent"
.../>
<Spinner
android:layout_width="match_parent"
.../>
</LinearLayout>
(I've added a background color to the LinearLayout to make it easier to see how it's sizing itself.)
Upvotes: 7
Reputation: 5579
Update: see my other answer for a better solution.
I wish there was a more elegant solution, but the way I've achieved this is by adding an additional hidden duplicate Spinner
view used just for sizing the parent LinearLayout
to achieve the max of either wrap_content
or match_parent
, depending on which is larger.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parentView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:textSize="12sp"
android:textColor="?android:textColorHint"
tools:text="Label" />
<Spinner
android:id="@+id/spinner"
style="@style/Widget.AppCompat.Spinner.Underlined"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- visible view width set to match_parent -->
<Spinner
android:id="@+id/spinnerHiddenSizer"
style="@style/Widget.AppCompat.Spinner.Underlined"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:visibility="invisible" />
<!-- invisible view width set to wrap_content -->
<!-- also set height to 0dp so it takes up no vertical space -->
<!-- in code, set this Spinner's adapter to the same as -->
<!-- the visible spinner so that it's sized the same -->
</LinearLayout>
This way, if wrap_content
would cause the Spinner
's width to be larger than match_parent
, the hidden view will cause the LinearLayout
to size to this larger size and the visible match_parent
width will expand to this width.
Upvotes: 0
Reputation: 1286
try setting the layout weight android:layout_weight
. here is a definition from SO: https://stackoverflow.com/a/3996104/8738574
.
set the weight of the spinner to be bigger to what the textView is, and the width to 0 (zero).
TextView:
android:layout_weight="1"
android:layout_width="0px"
Spinner:
android:layout_weight="2"
android:layout_width="0px"
Upvotes: 0
Reputation: 1310
The problem that your LinearLayout
width is wrap_content
. It means children will never fill full width, only if content inside will change width.
Just change line inside LinearLayout
. From:
android:layout_width="wrap_content"
To
android:layout_width="match_parent"
Upvotes: 0