Android
47
xmlns:app="http://schemas.android.com/apk/resauto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="?attr/homeAsUpIndicator" />
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
Небольшое примечание к этому коду:
обычно требуется, чтобы один эле
-
мент (в данном случае
AppBarLayout
, содержащий панель инструментов) зани
-
мал столько места, сколько ему нужно, а другой элемент заполнял остальное
пространство (это может быть
LinearLayout
или
ScrollView
). В данном случае
Fra
meLayout
, служащий контейнером для динамически добавляемых и удаляемых
представлений, будет занимать все пространство, доступное внутри его роди
-
теля.
Вы можете подумать, что в
FrameLayout
достаточно использовать константу
MATCH_PARENT
, но на самом деле родительский элемент имеет высоту, соответ
-
ствующую высоте экрана (при условии что он является корневым представле
-
нием), поэтому
FrameLayout
окажется обрезанным снизу на величину, равную
разности высоты экрана и высоты
Toolbar
. Показанный здесь трюк с
LinearLay
out
решает эту распространенную проблему: свойству представления, опреде
-
ляющему переменный размер, нужно присвоить значение
WRAP_CONTENT
, а тому
же свойству представления, которое должно заполнить оставшуюся часть про
-
странства в родительском элементе, нужно присвоить значение
0dp
и присво
-
ить свойству
layout_weight
значение
1
(на самом деле можно присвоить любое
значение). Весовое свойство сообщит
LinearLayout
, какой процент доступного
пространства нужно передать представлению.
Теперь мы имеем макет в файле ресурсов, предварительно скомпилирован
-
ный и готовый к работе. Как его использовать? Есть несколько способов, часть
из которых мы затронули в главе 1, когда рассматривали контроллеры поль
-
зовательского интерфейса. А сейчас давайте сосредоточимся на
паре общих
подходов и рассмотрим еще пару, реже встречающуюся на практике.
Один из способов заключается в назначении макета на роль корневого
представления в
Ac ti vi ty
. Просто вызовите
Ac ti vi ty.setContentView
и передайте
идентификатор
ресурса макета, например:
48
Представления
Java
public class MyAc ti vi ty extends Ac ti vi ty {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
}
}
Kotlin
class MyAc ti vi ty : Ac ti vi ty() {
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.my_activity)
}
}
Это все, что нужно! Когда
MyAc ti vi ty
запустится, вы сразу увидите на экране
дерево представлений, описанное в XML-файле макета.
Другой способ заключается в добавлении содержимого макета в существу
-
ющее дерево представлений. Если дерево представлений уже создано любым
другим способом, вы сможете довольно легко добавлять или удалять из него
экземпляры
View
, используя методы
ViewGroup
, например
ViewGro
up.addView
и
View
Grou
p.removeView
. Этот способ прекрасно подходит для представлений, создава
-
емых программно, но его точно так же можно использовать для явного раз
-
вертывания макета. Существует системная служба, которая может помочь вам
в этом, и есть два идентичных способа получить ссылку на эту службу:
Java
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
Kotlin
val inflater = context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
Второй способ:
Java
LayoutInflater inflater = LayoutInflater.from(context);
Kotlin
val inflater = LayoutInflater.from(context)
Получив
ссылку на экземпляр
inflater
, можно вызвать его метод
inflate
.
Первый вариант – добавление представлений, извлеченных из макета, в дру
-
гое представление
ViewGroup
, которое передается как параметр:
Java
inflater.inflate(R.layout.my_activity, someViewGroup, true);
Android
49
Kotlin
inflater.inflate(R.layout.my_activity, someViewGroup, true)
Метод с этой сигнатурой автоматически добавит развернутое дерево пред
-
ставлений в экземпляр, переданный во втором параметре (
som
eViewGroup
), и вер
-
нет прежний корень (
someViewG
roup
).
Второй вариант – вызов метода без корня:
Java
inflater.inflate(R.layout.my_activity, null);
Kotlin
inflater.inflate(R.layout.my_activity, null)
Преимущество этой версии в том, что она возвращает развернутое дерево
представлений, не добавляя его в существующее дерево представлений.
Кроме того, при
использовании фрагментов
Fragment
(также описывались
в главе 1) ваши экземпляры
Fragment
могут вернуть экземпляр
View
из своего
обратного вызова
onCreateView
(который автоматически вызывается при созда
-
нии фрагмента). Также классы диспетчеров представлений, такие как
Recycler
View
и
ViewPager
, позволяют переопределить обработчики, которые должны воз
-
вращать представление
View
по мере необходимости изменения отображения
(при прокрутке или листании).
Do'stlaringiz bilan baham: