Что означает Android: layout_weight?

Ответы:

860

С layout_weightего помощью можно указать соотношение размеров между несколькими видами. Например, у вас есть MapViewи, tableкоторые должны показать некоторую дополнительную информацию на карту. Карта должна использовать 3/4 экрана, а таблица - 1/4 экрана. Тогда вы будете установить layout_weightиз mapдо 3 , и layout_weightиз table1.

Чтобы это работало, вы также должны установить высоту или ширину (в зависимости от вашей ориентации) в 0px.

Фло
источник
208
пока вы не упомянули высоту 0px!
JohnnyLambada
24
Чтобы определить, какой из них будет зависеть от веса. Ширина или высота.
neteinstein
30
Вам нужен 0px. Пример: вы хотите реализовать таблицу с двумя столбцами одинакового размера. Каждая строка таблицы представляет собой горизонтальный линейный макет с двумя «ячейками таблицы» (например, TextViews), каждая из которых имеет layout_weight = .5. Если вы укажете layout_width = "wrap_content" в "ячейках таблицы", ширина содержимого будет добавлена ​​к ширине, рассчитанной по layout_weight, ячейки таблицы будут всех разных размеров, и столбцы не будут правильно выстроены. Поэтому вы должны установить layout_width = 0dp, чтобы android использовал layout_weight только для вычисления ширины ячеек.
Eeeeaaii
3
@Solace, поздний ответ, но ради полноты. Похоже, весовой атрибут не влияет на RelativeLayout. Работает только с LinearLayout. Если вы видите необходимость взвешивания, возможно, вам стоит создать LinearLayout (с весами) в RelativeLayout.
BBV
1
layout_weight работает только для линейного макета или будет работать для каждой группы представлений.
meShakti
247

В двух словах, 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_weight1, а второе текстовое поле имеет значение layout_weight2, то одна треть оставшегося пространства будет отдана первому, а две трети - второму (поскольку мы требуем второе один важнее).

Расчет:

1-я метка = 0 / (0 + 1 + 2)

2-е текстовое поле = 1 / (0 + 1 + 2)

3-е текстовое поле = 2 / (0 + 1 + 2)


Исходная статья

Ковчег
источник
19
Гораздо лучшее объяснение, чем выбранный в настоящее время ответ.
Тень
12
Ну, есть простое объяснение (которое я ценю) и мельчайшие детали (которые я ценю по-другому). Они оба хорошие ответы.
cbmanica
3
Как уже упоминалось, android:layout_width="0px"это важно. Кроме того, веса не должны быть целыми числами.
Брайан Уайт
Это немного сложнее понять, чем выбранный ответ, но он дает полный ответ - особенно когда некоторые представления имеют весовые коэффициенты, а некоторые - нет. Это огромный случай использования, не охваченный выбранным ответом.
Эйси
откуда же weightSumтогда картинка? Это как-то связано layout_weight?
eRaisedToX
72

добавляя к другим ответам, самое главное, чтобы это работало, это установить ширину макета (или высоту) в 0px

android:layout_width="0px"

в противном случае вы увидите мусор

roetzi
источник
Я думаю, это зависит от того, хотите ли вы скрыть представления, которые не определяют их вес, или вы хотите показать их с размером, соответствующим размеру, и оставить оставшееся свободное пространство для «взвешенных» представлений.
Андреа
Что делать, если мне нужно настроить как горизонтальный, так и вертикальный вес?
Олстон
40

Если существует несколько представлений, охватывающих a 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>
Suragch
источник
1
Мне всегда интересно, почему все больше людей не публикуют изображения, сопровождающие их XML. Гораздо проще понять визуальные эффекты, чем код.
AleksandrH
30

layout_weightговорит Android, как распределить ваши Viewв LinearLayout. Затем Android сначала вычисляет общую пропорцию, требуемую для всех Views, для которых указан вес, и размещает каждую в Viewсоответствии с той долей экрана, которая ему требуется. В следующем примере, Android видит , что TextViewей есть layout_weightиз 0(это по умолчанию) и EditTexts имеет 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>

Это выглядит так:
альбомная ориентация и
книжная ориентация

Таш Пемхива
источник
ссылка больше не доступна. Если у вас есть еще одна хорошая ссылка, пожалуйста, обновите.
BinaryGuy
16

Подумай так, будет проще

Если у вас есть 3 кнопки и их вес 1,3,1 соответственно, он будет работать как таблица в HTML

Обеспечьте 5 частей для этой строки: 1 часть для кнопки 1, 3 части для кнопки 2 и 1 часть для кнопки 1

Рассматривать,

Джордж Нгуен
источник
10

Одним из лучших объяснений для меня было это (из учебника по Android, ищите шаг 7) :

layout_weight используется в LinearLayouts для присвоения «важности» представлениям в макете. Все виды имеют по умолчанию layout_weight, равный нулю, что означает, что они занимают столько места на экране, сколько необходимо для отображения. Присвоение значения больше нуля разделит оставшуюся часть свободного пространства в родительском представлении в соответствии со значением layout_weight каждого представления и его отношением к общему layout_weight, указанному в текущем макете для этого и других элементов View.

Для примера: допустим, у нас есть текстовая метка и два элемента редактирования текста в горизонтальной строке. В метке не указан layout_weight, поэтому он занимает минимальное пространство, необходимое для визуализации. Если для layout_weight каждого из двух элементов редактирования текста задано значение 1, оставшаяся ширина в родительском макете будет разделена поровну между ними (поскольку мы утверждаем, что они одинаково важны). Если первый имеет layout_weight, равный 1, а второй имеет layout_weight, равный 2, то одна треть оставшегося пространства будет отдана первому, а две трети - второму (поскольку мы утверждаем, что второй является более важным).

Андре Стингресс
источник
4

Для дополнительного :

Для verticalориентации не забудьте установить height0dp

android:layout_height="0dp"

Для horizontalориентации не забудьте установить width0dp

android:layout_width="0dp"
Ален Ли
источник
3

Пожалуйста, посмотрите на 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>
Мин Леунг
источник
Пожалуйста, посмотрите на WeightSum of LinearLayout и layout_weight каждого вида. android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" Их layout_height имеют значение 0px, но я не уверен, что это актуально.
Мин Леунг
0

Объединяя оба ответа от

Flo & rptwsthi и roetzi,

Не забудьте изменить свое layout_width=0dp/px, иначе layout_weightповедение будет действовать в обратном порядке: наибольшее число занимало наименьшее пространство, а наименьшее число занимало наибольшее пространство.

Кроме того, некоторая комбинация весов приведет к тому, что какая-то раскладка не может быть показана (так как она занимала пространство).

Остерегайтесь этого.

user2837483
источник
0

Добавление android:autoSizeTextType="uniform"изменит размер текста для вас автоматически

skryshtafovych
источник
-1

Как следует из названия, Layout weight указывает, какой объем или процент пространства определенного поля или виджета должен занимать пространство экрана.
Если мы указываем вес в горизонтальной ориентации, то мы должны указать layout_width = 0px.
Точно так же, если мы указываем вес в вертикальной ориентации, то мы должны указать layout_height = 0px.

Akanksha Hegde
источник