Flexible horizontal layout with `layout_weight` and` maxWidth`

I have a TextView and an ImageView square that I would like to show in a horizontal linear layout. Each of them should take half the width of the representation of the parent element, and the height should correspond to the content (i.e. the image). The text should be centered vertically.

An additional limitation is that the image should not grow beyond the specified maxWidth (= maxHeight ), and excess width should be available for the TextView . Obviously, this is contrary to rule 50/50 above. Is there a way to prioritize constraints i.e. Allow the image to take half the space if it does not exceed a given size?

desired result

These are the layouts I tried:

The first of them perfectly stretches the left side to the available space. But the image takes up more than half the width, because its layout_weight not specified (as shown in the figure below).

 <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:orientation="vertical" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Some text."/> </LinearLayout> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxWidth="200dp" android:adjustViewBounds="true" android:src="@drawable/image" /> </LinearLayout> 

without <code> layout_weight </code>

When I add layout_weight to the ImageView , it always takes half the width and ignores maxWidth (see the figure below).

  <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:maxWidth="200dp" android:adjustViewBounds="true" android:src="@drawable/image" /> 

with <code> layout_weight </code>

Including ImageView in another LinearLayout again includes maxWidth , but the included LinearLayout still takes up half the available space (see image below).

  <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="right"> <ImageView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:maxWidth="200dp" android:adjustViewBounds="true" android:src="@drawable/image" /> </LinearLayout> 

using include <code> LinearLayout </code>

Another option I found for such scenarios is to use a RelativeLayout with an invisible view as the center separator, but this blocks 50/50 division (or wherever the separator is located).

+5
source share
3 answers

Ok, I'm going to go ahead and publish the xml I created, it is pretty simple, it fulfills most of your conditions. One thing I'm having problems with is the part in which each view occupies half the width of the parent's view. I hope this helps you anyway.

sample_layout.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="2dp" android:background="@android:color/darker_gray"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/img_sample" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginRight="2dp" android:layout_toLeftOf="@id/img_sample" android:background="@color/colorPrimary" android:gravity="center_vertical" android:text="Some text." /> <ImageView android:id="@id/img_sample" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginLeft="2dp" android:adjustViewBounds="true" android:maxWidth="200dp" android:src="@drawable/sample_img" /> </RelativeLayout> 

Here is an example screenshot: enter image description here

If you ever learn how to do half of each thing, comment on it here. It would be nice to know about this for possible future use. :)

PS: Have you considered doing half of each thing programmatically? Like checking LayoutParams , then dynamically setting weightSum and layout_weight s.

Sample image extracted from this link

+2
source
 <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentTop="true" android:layout_weight="1" android:adjustViewBounds="true" android:background="@color/blue" android:src="@drawable/ic_launcher" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_margin="5dp" android:layout_toStartOf="@id/imageView" android:background="@color/colorPrimary" android:padding="10dp" android:text="Some text. " /> </RelativeLayout> 

This is how it looks

0
source

This would not be an ideal solution in terms of performance. But you can achieve this by playing with FrameLayout and ImageView.

Here is the result: enter image description here enter image description here

layout.xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/textGray" android:orientation="vertical"> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/skyBlue"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:background="@android:color/white"> <ImageView android:id="@+id/imageView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxWidth="200dp" android:src="@drawable/ic_settings" android:visibility="invisible" /> <TextView android:id="@+id/TextView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:text="!" /> </FrameLayout> <ImageView android:id="@+id/imageView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:maxWidth="200dp" android:src="@drawable/ic_settings" /> </LinearLayout> </FrameLayout> </LinearLayout> 

To achieve the desired behavior, you will need to set the same images for both images in this layout. one of them is invisible, it just helps to make the parent with the same width and heights, which will lead us to create a TextView with the same dimensions.
Note. If you want to change the alignment of the textView, you can do this with layout_gravity or gravity.

0
source

Source: https://habr.com/ru/post/1245157/


All Articles