我在布局中有两个视图。
我会分别称他们为View A
和View B
。
┌──────┐
│┌─┐┌─┐│
││A││B││
│└─┘└─┘│
└──────┘
父级布局(包括View A
和View B
)的高度为WRAP_CONTENT
。
此处,View B
的高度为WRAP_CONTENT
。也就是说,它的高度可以根据其内容而改变。
我想做的是
View A
的内容短于View B
的内容,请将View A
的身高设置为View B
的身高。View A
的内容高于View A
的内容,请将View B
的高度设置为自己内容的高度。所以,
①如果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.
我该如何解决这个问题?
答案 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>