Что означает 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,

Другие вопросы по тегам