如果兄弟视图较大,则为MATCH_PARENT,如果兄弟视图较小,则为WRAP_CONTENT

时间:2013-06-15 00:46:10

标签: android android-layout

我在布局中有两个视图。 我会分别称他们为View AView B

┌──────┐
│┌─┐┌─┐│
││A││B││
│└─┘└─┘│
└──────┘

父级布局(包括View AView B)的高度为WRAP_CONTENT

此处,View B的高度为WRAP_CONTENT。也就是说,它的高度可以根据其内容而改变。

我想做的是

  1. 如果View A的内容短于View B的内容,请将View A的身高设置为View B的身高。
  2. 如果View A的内容高于View A的内容,请将View B的高度设置为自己内容的高度。
  3. 所以,

    ①如果View B的内容较高,则View A的身高设置为View B的身高。

           ┌──────┐      ┌──────┐
           │┌─┐┌─┐│      │┌─┐┌─┐│
           ││ ││ ││      ││A││ ││
    I want ││A││B││, not │└─┘│B││.
           ││ ││ ││      │   │ ││
           │└─┘└─┘│      │   └─┘│
           └──────┘      └──────┘
    

    ②如果View B的内容较短,则View A的身高为View A自己的身高。

           ┌──────┐      ┌──────┐
           │┌─┐┌─┐│      │┌─┐┌─┐│
           ││ ││B││      ││A││B││
    I want ││A│└─┘│, not │└─┘└─┘│.
           ││ │   │      └──────┘
           │└─┘   │
           └──────┘
    

    如果父级为LinearLayout (Horizontal),则将View A的高度设置为WRAP_CONTENT会违反案例1,将View A的高度设置为MATCH_PARENT会违反案例2。

    如果父级为RelativeLayout,则将View A设置为与其父级的顶部和底部对齐会违反RelativeLayout的条件: Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM.

    我该如何解决这个问题?

3 个答案:

答案 0 :(得分:6)

有不同的方法可以解决此问题,例如创建自己的自定义ViewGroup,可能基于水平LinearLayout。但是,我认为最直接的解决方案是在运行时动态设置需求。

在水平TextView中只考虑两个LinearLayout s考虑以下布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#f00"
    android:padding="10dp" >

    <TextView
        android:id="@+id/first"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#0f0"
        android:padding="5dp"
        android:text="One line" />

    <TextView
        android:id="@+id/second"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00f"
        android:padding="5dp"
        android:text="Two\nlines"
        android:textColor="#fff" />

</LinearLayout>

两者都包裹它们的高度,这基本符合您的第一个要求。

现在要求2:为了演示目的,我将第二个TextView的文本分成两行,以使其高于第一行。要使第一个TextView匹配它的高度,您所要做的就是:

LinearLayout container = (LinearLayout) findViewById(R.id.container);
final TextView first = (TextView) findViewById(R.id.first);
final TextView second = (TextView) findViewById(R.id.second);

container.post(new Runnable() {
    @Override public void run() {
        int h1 = first.getMeasuredHeight();
        int h2 = second.getMeasuredHeight();
        if (h1 < h2) first.getLayoutParams().height = h2;

    }
});

'技巧'是发布到视图的队列中,确保在测量子节点并且具有有效高度之前逻辑不会被执行。对于要求2,如果第二个视图更高,则只需要更改第一个视图的高度,这正是run()方法中的部分所做的。

答案 1 :(得分:1)

您需要使用布局参数以编程方式设置视图的尺寸。假设您使用LinearLayout来保存视图,这就是您要做的事情:

//the views are called a and b
LinearLayout.LayoutParams aParams = a.getLayoutParams();
LinearLayout.LayoutParams bParams = b.getLayoutParams();
int aWidth = aParams.width;
int aHeight = aParams.height;
int bWidth = bParams.width;
int bHeight = bParams.height;
if (aHeight >= bHeight) {
    // do nothing
}
else {
    a.setLayoutParams(new LinearLayout.LayoutParams(aWidth, bHeight));
}

当你设置它们的高度时,最初在修改之前将它们保存为xml中的wrap_content。

答案 2 :(得分:1)

这可以很容易地从axml中解决。

将父布局的高度保持为wrap_content,并将每个子视图的高度设置为match_parent。这将导致父布局的高度换到最高的子级,并且每个子视图的高度都会延伸到父级。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="text" />
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="match_parent"
      android:text="More\ntext" />
</LinearLayout>