简体   繁体   中英

Flexible Horizontal Layout with `layout_weight` and `maxWidth`

I have a TextView and a square ImageView that I would like to show in a horizontal linear layout. Each should take half of the parent view's width and the height should fit the content (ie the image). The text should be centered vertically.

Additional constraint is that the image should not grow beyond a given maxWidth (= maxHeight ), and excess width should be made available to the TextView . Obviously, this conflicts with the 50/50 rule above. Is there a way to prioritize the constraints, ie allow the image to take half of the space unless it exceeds a given size?

期望的结果

These are layouts I tried:

The first one nicely stretches the left side to the available space. But the image takes more than half of the width as its layout_weight is not specified (as in image 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>

没有<code> layout_weight </ code>

When I add layout_weight to the ImageView it always takes half of the width and ignore the maxWidth (see image 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" />

使用<code> layout_weight </ code>

Enclosing the ImageView in another LinearLayout enables the maxWidth again, but the enclosing LinearLayout still takes half of 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>

使用封闭的<code> LinearLayout </ code>

Another option I have found for similar scenarios is to use a RelativeLayout with an invisible view as a center divider, but that locks the division to 50/50 (or wherever the divider is placed).

Okay, gonna go on ahead and post the xml I created, it's pretty much simple, it does most of your conditions.. One thing I'm having trouble with is the part where each view takes half of the parent view's width. Hope this still helps you in some way.

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 a sample screenshot: 在此输入图像描述

If ever you figure out how to the the half of each thing, kindly comment it here, It'd be nice to know about it for possible future use. :)

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

Sample Image retrieved from this link

<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>

这是它的样子

It won't be a perfect solution in term of performance. But you can achieve it by playing with FrameLayout and ImageView.

Here is the output: 在此输入图像描述 在此输入图像描述

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>

In order to achieve desire behaviour, You would have to set same images to both imagesviews in this layout. one of them is invisble, It is just helping to make parent with same width and heights which would lead us to create TextView with same dimensions.
Note: If you want to change textView alignment, you can do it with layout_gravity or gravity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM