Ответ 1
Я исследовал эту проблему, ссылаясь на Документы LayoutInflater и создав небольшой демонстрационный проект. В следующих руководствах показано, как динамически заполнять макет с помощью LayoutInflater
.
Прежде чем мы начнем, посмотрим, как выглядят параметры LayoutInflater.inflate()
:
- ресурс: идентификатор ресурса макета XML для загрузки (например,
R.layout.main_page
) - root. Необязательный вид, который должен быть родителем сгенерированной иерархии (если
attachToRoot
istrue
), или просто объект, предоставляющий набор значенийLayoutParams
для корня из возвращенная иерархия (еслиattachToRoot
-false
.) -
attachToRoot: следует ли привязать завышенную иерархию к корневому параметру? Если false, root используется только для создания правильного подкласса
LayoutParams
для корневого представления в XML. -
Возвращает: корневой вид завышенной иерархии. Если был указан корневой каталог, а
attachToRoot
-true
, это будет root; в противном случае это корень завышенного XML файла.
Теперь для образца макета и кода.
Основной макет (main.xml
):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
В этот контейнер добавлен отдельный TextView, видимый как маленький красный квадрат, если параметры макета успешно применяются из XML (red.xml
):
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="#ff0000"
android:text="red" />
Теперь LayoutInflater
используется с несколькими вариантами параметров вызова
public class InflaterTest extends Activity {
private View view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewGroup parent = (ViewGroup) findViewById(R.id.container);
// result: layout_height=wrap_content layout_width=match_parent
view = LayoutInflater.from(this).inflate(R.layout.red, null);
parent.addView(view);
// result: layout_height=100 layout_width=100
view = LayoutInflater.from(this).inflate(R.layout.red, null);
parent.addView(view, 100, 100);
// result: layout_height=25dp layout_width=25dp
// view=textView due to attachRoot=false
view = LayoutInflater.from(this).inflate(R.layout.red, parent, false);
parent.addView(view);
// result: layout_height=25dp layout_width=25dp
// parent.addView not necessary as this is already done by attachRoot=true
// view=root due to parent supplied as hierarchy root and attachRoot=true
view = LayoutInflater.from(this).inflate(R.layout.red, parent, true);
}
}
Фактические результаты изменений параметров документируются в коде.
СИНТАКСИС: Вызов LayoutInflater
без указания root приводит к раздуванию вызова, игнорируя параметры макета из XML. Вызов inflate с корнем, не равным null
и attachRoot=true
, загружает параметры макета, но снова возвращает объект root, что предотвращает дальнейшие изменения макета для загруженного объекта (если вы не можете найти его с помощью findViewById()
).
Вызывающая конвенция, которую вы, скорее всего, хотели бы использовать, является следующим:
loadedView = LayoutInflater.from(context)
.inflate(R.layout.layout_to_load, parent, false);
Чтобы помочь с проблемами макета, рекомендуется просмотрщик иерархии.