Действительно ли работает XML-макет Android "включить" тег?
Я не могу переопределить атрибуты при использовании <include> в моих файлах макета Android. Когда я искал ошибки, я нашел Declined Issue 2863:
"включить тег (нарушающий параметры макета никогда не работает)
Поскольку Ромен указывает, что это работает в наборах тестов и его примерах, я должен делать что-то неправильно.
Мой проект организован следующим образом:
res/layout
buttons.xml
res/layout-land
receipt.xml
res/layout-port
receipt.xml
В файле buttons.xml есть что-то вроде этого:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button .../>
<Button .../>
</LinearLayout>
И файлы портрета и landscape receipt.xml выглядят примерно так:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
...
<!-- Overridden attributes never work. Nor do attributes like
the red background, which is specified here. -->
<include
android:id="@+id/buttons_override"
android:background="#ff0000"
android:layout_width="fill_parent"
layout="@layout/buttons"/>
</LinearLayout>
Что мне не хватает?
Ответы
Ответ 1
Я только что нашел проблему. Во-первых, вы можете только переопределить атрибуты layout_ *, поэтому фон не будет работать. Это документированное поведение и просто контроль с моей стороны.
Реальная проблема находится в LayoutInflater.java:
// We try to load the layout params set in the <include /> tag. If
// they don't exist, we will rely on the layout params set in the
// included XML file.
// During a layoutparams generation, a runtime exception is thrown
// if either layout_width or layout_height is missing. We catch
// this exception and set localParams accordingly: true means we
// successfully loaded layout params from the <include /> tag,
// false means we need to rely on the included layout params.
ViewGroup.LayoutParams params = null;
try {
params = group.generateLayoutParams(attrs);
} catch (RuntimeException e) {
params = group.generateLayoutParams(childAttrs);
} finally {
if (params != null) {
view.setLayoutParams(params);
}
}
Если значение <include> тег не включает и layout_width и layout_height, возникает RuntimeException и бесшумно обрабатывается без какой-либо записи журнала.
Решение состоит в том, чтобы всегда включать как layout_width, так и layout_height при использовании <include> тег, если вы хотите переопределить любые атрибуты layout_ *.
Мой пример должен измениться на:
<include
android:id="@+id/buttons_override"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="@layout/buttons"/>
Ответ 2
Я отправил запрос улучшения, чтобы разрешить переопределение всех включенных атрибутов:
Предположим, что у меня есть два идентичных макета, отличных от значений a TextView
. В настоящее время я либо модифицировал макет в время выполнения или дублирование XML.
Например, чтобы передать два параметра со значениями "hello" и "world" в layout1:
<include layout="@layout/layout1a"
params="textView=hello|editText=world" />
layout1a.xml:
<merge><TextView text="@param/textView"><EditText
hint="@param/editText"></merge>
Альтернативная реализация нарушит инкапсуляцию и позволит оператор include для переопределения таких значений, как:
<include layout="@layout/layout1b"
overrides="@id/textView.text=hello|@id/editText.hint=world" />
layout1b.xml:
<merge><TextView id="@+id/textView"><EditText
hint="@+id/editText"></merge>
Ответ 3
Я обнаружил, что иногда пропускаю, включая тег android: id при использовании построителя GUI в Eclipse. Убедившись (когда я замечаю), что я добавляю в TextView от строителя, идентификатор, который я использую в макете ListView.
<TextView android:text="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
...
становится
<TextView android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
...
Вместо того, чтобы "false" false, я получаю:) и включает в себя работу в порядке.