MATCH_PARENT, если вид на сестры больше, WRAP_CONTENT, если вид сестры меньше
У меня есть два вида в макете.
Я назову их View A
и View B
соответственно.
┌──────┐
│┌─┐┌─┐│
││A││B││
│└─┘└─┘│
└──────┘
Высота родительского макета (включая View A
и View B
) равна WRAP_CONTENT
.
Здесь высота View B
равна WRAP_CONTENT
. То есть его высота может быть изменена по отношению к ее содержимому.
Что я хочу сделать, это
- Установите высоту
View A
height до View B
height, если содержимое View A
меньше View B
.
- Установите высоту
View A
в свою собственную высоту контента, если содержимое View A
выше, чем View B
.
Итак,
① Если содержимое View B
выше, то высота View A
установлена на View B
height.
┌──────┐ ┌──────┐
│┌─┐┌─┐│ │┌─┐┌─┐│
││ ││ ││ ││A││ ││
I want ││A││B││, not │└─┘│B││.
││ ││ ││ │ │ ││
│└─┘└─┘│ │ └─┘│
└──────┘ └──────┘
② Если содержимое View B
короче, то View A
высота View A
имеет собственную высоту коннектора.
┌──────┐ ┌──────┐
│┌─┐┌─┐│ │┌─┐┌─┐│
││ ││B││ ││A││B││
I want ││A│└─┘│, not │└─┘└─┘│.
││ │ │ └──────┘
│└─┘ │
└──────┘
Если родительский элемент LinearLayout (Horizontal)
, установка View A
height на WRAP_CONTENT
нарушает регистр 1, а установка View A
height на 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.
Как я могу решить эту проблему?
Ответы
Ответ 1
Существуют разные способы сделать это, например, создав собственный пользовательский ViewGroup
, возможно, на основе горизонтального LinearLayout
. Тем не менее, я считаю, что наиболее простым решением было бы динамическое определение требований во время выполнения.
Рассмотрим следующий макет с двумя TextView
в горизонтальном LinearLayout
:
<?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()
.
Ответ 2
Вам необходимо установить размеры представлений программным образом с помощью параметров макета. Предполагая, что вы используете 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));
}
Когда вы устанавливаете свои высоты, сначала сохраняйте их как wrap_content в xml до этой модификации.
Ответ 3
Это можно решить очень легко, только из 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>