具有“layout_weight”和“maxWidth”的灵活水平布局

Flexible Horizontal Layout with `layout_weight` and `maxWidth`

我有一个 TextView 和一个正方形 ImageView,我想以水平线性布局显示它们。每个都应该占据父视图宽度的一半,高度应该适合内容(即图像)。文本应垂直居中。

额外的限制是图像不应超过给定的 maxWidth (= maxHeight),并且应为 TextView 提供多余的宽度。显然,这与上面的 50/50 规则相冲突。有没有办法确定约束的优先级,即允许图像占 space 的一半,除非它超过给定的大小?

这些是我试过的布局:

第一个很好地将左侧延伸到可用 space。但是由于未指定 layout_weight(如下图所示),图像占据了一半以上的宽度。

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

当我将 layout_weight 添加到 ImageView 时,它总是占宽度的一半并忽略 maxWidth(见下图)。

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

ImageView 包含在另一个 LinearLayout 中再次启用 maxWidth,但封闭的 LinearLayout 仍然占用可用 space 的一半(见图下面)。

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

我为 similar scenarios 找到的另一个选项是使用具有不可见视图的 RelativeLayout 作为中心分隔线,但这会将分隔锁定为 50/50(或放置分隔线的任何位置) ).

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

好的,继续 post 我创建的 xml,它非常简单,它满足你的大部分条件。我遇到的一件事是部分每个视图占据父视图宽度的一半。希望这仍然能以某种方式帮助你。

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>

这是一个示例屏幕截图:

如果你想出了如何把每个一半的事情弄清楚,请在这里发表评论,很高兴了解它以备将来使用。 :)

PS:您是否考虑过以编程方式完成每个一半的事情?就像检查 LayoutParams 然后动态设置 weightSumlayout_weights.

从此 link

检索到的示例图像

就性能而言,这不是一个完美的解决方案。但是您可以通过使用 FrameLayout 和 ImageView 来实现它。

输出如下:

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>

为了实现期望的行为,您必须为此布局中的两个图像视图设置相同的图像。其中之一是不可见的,它只是帮助使父级具有相同的宽度和高度,这将导致我们创建具有相同尺寸的 TextView。
注意: 如果你想改变textView的对齐方式,你可以用layout_gravity或者gravity。