Что означает Android:layout_weight?
Я не понимаю, как использовать этот атрибут. Кто-нибудь может рассказать мне больше об этом?
13 ответов
С layout_weight
Вы можете указать соотношение размеров между несколькими представлениями. Например, у вас есть MapView
и table
который должен показать некоторую дополнительную информацию на карту. Карта должна использовать 3/4 экрана, а таблица - 1/4 экрана. Тогда вы установите layout_weight
из map
до 3 а layout_weight
из table
до 1.
Чтобы заставить его работать, вы также должны установить высоту или ширину (в зависимости от вашей ориентации) в 0px.
В двух словах, layout_weight
указывает, сколько дополнительного пространства в макете будет выделено для представления.
LinearLayout поддерживает назначение веса отдельным детям. Этот атрибут присваивает представлению значение важности и позволяет ему расширяться, чтобы заполнить все оставшееся пространство в родительском представлении. Вес просмотров по умолчанию равен нулю.
Расчет, чтобы назначить любое оставшееся пространство между дочерними
В общем, формула имеет вид:
пространство, назначенное ребенку = (индивидуальный вес ребенка) / (сумма веса каждого ребенка в линейном расположении)
Пример 1
Если есть три текстовых поля и два из них объявляют вес 1, а третьему не присваивается вес (0), то оставшееся пространство присваивается следующим образом:
1-е текстовое поле = 1/(1+1+0)
2-е текстовое поле = 1/(1+1+0)
3-е текстовое поле = 0/(1+1+0)
Пример 2
Допустим, у нас есть текстовая метка и два элемента редактирования текста в горизонтальной строке. На этикетке нет layout_weight
указано, поэтому он занимает минимальное пространство, необходимое для визуализации. Если layout_weight
для каждого из двух элементов редактирования текста установлено значение 1, оставшаяся ширина в родительском макете будет разделена поровну между ними (поскольку мы утверждаем, что они одинаково важны).
Расчет:
1-я метка = 0 / (0 + 1 + 1)
2-е текстовое поле = 1/(0+1+1)
3-е текстовое поле = 1/(0+1+1)
Если вместо этого первое текстовое поле имеет layout_weight
1, а второе текстовое поле имеет layout_weight
из 2, тогда одна треть оставшегося пространства будет отдана первой, а две трети - второй (потому что мы утверждаем, что вторая важнее).
Расчет:
1-я метка = 0 / (0 + 1 + 2)
2-е текстовое поле = 1 / (0 + 1 + 2)
3-е текстовое поле = 2/(0+1+2)
Добавляя к другим ответам, самое главное, чтобы это работало, это установить ширину макета (или высоту) в 0px
android:layout_width="0px"
в противном случае вы увидите мусор
Если есть несколько представлений, охватывающих LinearLayout
, затем layout_weight
дает им каждый пропорциональный размер. Вид с большим layout_weight
значение "весит" больше, поэтому оно становится больше.
Вот изображение, чтобы прояснить ситуацию.
теория
Термин "вес макета" связан с понятием взвешенного среднего по математике. Это как в классе колледжа, где домашнее задание стоит 30%, посещаемость - 10%, промежуточный - 20%, а финальный - 40%. Ваши оценки по этим частям, при взвешивании вместе, дают вам общую оценку.
То же самое для веса макета. Views
в горизонтальном LinearLayout
каждый может занять определенный процент от общей ширины. (Или процент от высоты для вертикали LinearLayout
.)
Расположение
LinearLayout
то, что вы используете, будет выглядеть примерно так:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- list of subviews -->
</LinearLayout>
Обратите внимание, что вы должны использовать layout_width="match_parent"
для LinearLayout
, Если вы используете wrap_content
тогда это не сработает. Также обратите внимание, что layout_weight
не работает для представлений в RelativeLayouts (см. здесь и здесь ответы SO, касающиеся этой проблемы).
Виды
Каждый вид по горизонтали LinearLayout
выглядит примерно так:
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
Обратите внимание, что вам нужно использовать layout_width="0dp"
вместе с layout_weight="1"
, Забывание этого вызывает много новых проблем пользователей. (См. Эту статью для других результатов, которые вы можете получить, не устанавливая ширину равной 0.) Если ваши представления в вертикальной LinearLayout
тогда вы бы использовали layout_height="0dp"
, конечно.
в Button
В примере выше я установил вес на 1, но вы можете использовать любое число. Только общее значение имеет значение. Вы можете видеть в трех рядах кнопок на первом изображении, которое я разместил, все цифры разные, но, поскольку пропорции одинаковы, взвешенная ширина не меняется в каждой строке. Некоторым людям нравится использовать десятичные числа с суммой 1, чтобы в сложном макете было ясно, каков вес каждой части.
Последнее замечание Если у вас есть много вложенных макетов, которые используют layout_weight
, это может быть плохо для производительности.
дополнительный
Вот макет XML для верхнего изображения:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="android:layout_weight="
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="2" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="android:layout_weight="
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="10"
android:text="10" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="20"
android:text="20" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="10"
android:text="10" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="android:layout_weight="
android:textSize="24sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:text=".25" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".50"
android:text=".50" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:text=".25" />
</LinearLayout>
</LinearLayout>
layout_weight
говорит Android, как раздавать View
в LinearLayout
, Android сначала вычисляет общую пропорцию, необходимую для всех View
s, которые имеют определенный вес и размещают каждый View
в зависимости от того, какую часть экрана он указал, он нуждается. В следующем примере Android видит, что TextView
с layout_weight
из 0
(это значение по умолчанию) и EditText
с layout_weight
из 2
каждый, в то время как Button
имеет вес 1
, Таким образом, Android выделяет "достаточно" места для отображения tvUsername
а также tvPassword
а затем делит оставшуюся часть ширины экрана на 5 равных частей, две из которых выделяются etUsername
два к etPassword
и последняя часть bLogin
:
<LinearLayout android:orientation="horizontal" ...>
<TextView android:id="@+id/tvUsername"
android:text="Username"
android:layout_width="wrap_content" ... />
<EditText android:id="@+id/etUsername"
android:layout_width="0dp"
android:layout_weight="2" ... />
<TextView android:id="@+id/tvPassword"
android:text="Password"
android:layout_width="wrap_content" />
<EditText android:id="@+id/etPassword"
android:layout_width="0dp"
android:layout_weight="2" ... />
<Button android:id="@+id/bLogin"
android:layout_width="0dp"
android:layout_weight="1"
android:text="Login"... />
</LinearLayout>
Это выглядит как:
а также
Подумай так, будет проще
Если у вас есть 3 кнопки и их вес 1,3,1 соответственно, он будет работать как таблица в HTML
Обеспечьте 5 частей для этой строки: 1 часть для кнопки 1, 3 части для кнопки 2 и 1 часть для кнопки 1
Рассматривать,
Одним из лучших объяснений для меня было это (из учебника по Android, ищите шаг 7):
layout_weight используется в LinearLayouts для присвоения "важности" представлениям в макете. Все виды имеют по умолчанию layout_weight, равный нулю, что означает, что они занимают столько места на экране, сколько необходимо для отображения. Присвоение значения больше нуля разделит остальную часть доступного пространства в родительском представлении в соответствии со значением layout_weight каждого представления и его отношением к общему layout_weight, указанному в текущем макете для этого и других элементов View.
Для примера: допустим, у нас есть текстовая метка и два элемента редактирования текста в горизонтальной строке. В метке не указан layout_weight, поэтому он занимает минимальное пространство, необходимое для визуализации. Если для layout_weight каждого из двух элементов редактирования текста задано значение 1, оставшаяся ширина в родительском макете будет разделена поровну между ними (поскольку мы утверждаем, что они одинаково важны). Если первый имеет layout_weight, равный 1, а второй имеет layout_weight, равный 2, то треть оставшегося пространства будет отдана первому, а две трети - второму (поскольку мы утверждаем, что второй является более важным).
Для дополнительного:
За vertical
ориентация, не забудьте установить height
до 0dp
android:layout_height="0dp"
За horizontal
ориентация, не забудьте установить width
до 0dp
android:layout_width="0dp"
http://developer.android.com/guide/topics/ui/layout-objects.html
layout_weight определяет, сколько места должен получить элемент управления соответственно другим элементам управления.
Пожалуйста, посмотрите на WeightSum of LinearLayout и layout_weight каждого вида. android:weightSum="4" android:layout_weight="2" android:layout_weight="2" Их layout_height равны 0px, но я не уверен, что это актуально
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4">
<fragment android:name="com.example.SettingFragment"
android:id="@+id/settingFragment"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="2"
/>
<Button
android:id="@+id/dummy_button"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="2"
android:text="DUMMY"
/>
</LinearLayout>
Объединяя оба ответа от
Flo & rptwsthi и roetzi,
Не забудьте изменить свой layout_width=0dp/px
иначе layout_weight
Поведение будет действовать в обратном порядке: наибольшее число будет занимать наименьшее пространство, а минимальное - наибольшее
Кроме того, некоторая комбинация весов приведет к тому, что какая-то раскладка не будет отображаться (так как она занимала пространство).
Остерегайтесь этого.
Добавление android:autoSizeTextType="uniform"
изменит текст для вас автоматически
Как следует из названия, Layout weight указывает, какой объем или процент пространства определенного поля или виджета должен занимать пространство экрана.
Если мы указываем вес в горизонтальной ориентации, то мы должны указать layout_width = 0px
,
Точно так же, если мы указываем вес в вертикальной ориентации, то мы должны указать layout_height = 0px
,