Что такое Android:weightSum в Android, и как это работает?


Я хочу знать: что такое android: weightSum и вес макета, и как они работают?

9 137

9 ответов:

в документации, android:weightSum определяет максимальную сумму веса, и рассчитывается как сумма layout_weight всех детей, если не указан явно.

давайте рассмотрим пример с LinearLayout С горизонтальной ориентацией и 3 ImageViews внутри него. Теперь мы хотим эти ImageViews всегда равное пространство. Чтобы достичь этого, вы можете установить layout_weight каждого ImageView 1, а weightSum будет рассчитано равным 3, как показано на рисунке комментировать.

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    <!-- android:weightSum="3" -->
    android:orientation="horizontal"
    android:layout_gravity="center">

   <ImageView
       android:layout_height="wrap_content"       
       android:layout_weight="1"
       android:layout_width="0dp"/>
  .....

weightSum полезно для правильного отображения макета для любого устройства, что не произойдет, если вы установите ширину и высоту напрямую.

добавляя к ответу суперма и Джеффа,

Если в LinearLayout есть 2 вида, Первый с layout_weight равным 1, второй с layout_weight равным 2 и не указан весовой коэффициент, по умолчанию весовой коэффициент рассчитывается как 3 (сумма весов детей), и первый вид занимает 1/3 пространства, а второй-2/3.

однако, если бы мы определили weightSum как 5, первый занял бы 1/5 пространства, а второй взял бы 2/5. Таким образом, в общей сложности 3/5 пространства будет занято макетом, сохраняя остальные пустыми.

The документация говорит, что это лучшее и включает в себя пример (выделение мое).

android: weightSum

определяет максимальную сумму веса. Если не указано, сумма вычисляется по формуле добавление layout_weight всех детей. Это можно использовать для экземпляр, чтобы дать один ребенок 50% от общего доступного пространства давая ему layout_weight 0,5 и установив weightSum в 1.0.

Итак, чтобы исправить пример суперма, предположим, что у вас есть LinearLayout с горизонтальной ориентацией, которая содержит два ImageViews и TextView С. Вы определяете TextView иметь фиксированный размер, и вы хотели бы два ImageViews, чтобы занять оставшееся пространство поровну.

для достижения этой цели, вы бы применить layout_weight 1 Каждому ImageView, ни на TextView и weightSum 2.0 на LinearLayout.

после некоторых экспериментов, я думаю, что алгоритм LinearLayout таков:

предположим, что weightSum значение. Случай отсутствия обсуждается позже.

во-первых, разделить weightSum по количеству элементов whith match_parent или fill_parent в размерности LinearLayout (например layout_width на orientation="horizontal"). Мы будем называть это значение множителем веса w_m для каждого элемента. Значение по умолчанию для weightSum равно 1,0, поэтому множитель веса по умолчанию равен 1/n, где n число fill_parent элементы; wrap_content элементы не способствуют n.

w_m = weightSum / #fill_parent

например, когда weightSum это 60, а есть 3 fill_parent элементы, множитель веса составляет 20. Множитель веса является значением по умолчанию, например,layout_width если атрибут отсутствует.

во-вторых, вычисляется максимально возможное расширение каждого элемента. Во-первых,wrap_content элементы вычисляются в соответствии с их содержанием. Их расширение вычитается из расширения родительского контейнера. Мы будем называть оставшийся expansion_remainer. Этот остаток распределяется между fill_parent элементы в соответствии с их layout_weight.

в-третьих, расширение каждого fill_parent элемент рассчитывается как:

w_m - ( layout_weight / w_m ) * maximum_possible_expansion

пример:

если weightSum это 60, а есть 3 fill_parent элементы с весами 10, 20 и 30, их расширение на экране 2/3, 1/3 и 0/3 из родительский контейнер.

weight | expansion
     0 | 3/3
    10 | 2/3
    20 | 1/3
    30 | 0/3
    40 | 0/3

минимальное расширение ограничено на 0. Максимальное расширение ограничено родительским размером, т. е. веса ограничены 0.

если элемент wrap_content, его расширение вычисляется первым, а оставшееся расширение подлежит распределению среди fill_parent элементы. Если weightSum установлено, это приводит к layout_weight не оказывает никакого влияния на wrap_content элементы. Однако,wrap_content элементы можно все еще нажать из видимой области мимо элементы, вес которых ниже weight multiplier (например, между 0-1 для weightSum= 1 или между 0-20 для приведенного выше примера).

, если не weightSum указывается, вычисляется как сумма всех layout_weight ценностей в том числе с элементами wrap_content set! Так что layout_weight установить на wrap_content элементов можете повлиять на их расширение. Например, отрицательный вес будет сжимать другой fill_parent элементы. Перед fill_parent элементы выложены, будет выше формула применяется к wrap_content элементы, причем максимально возможное расширение является их расширением в соответствии с завернутым содержимым. Элемент wrap_content элементы будут сокращены, а затем максимально возможное расширение для оставшихся fill_parent элементы вычисляются и распределяются.

это может привести к сложным результатам.

Weight sum работает именно так, как вы хотите (как и другие ответы, вам не нужно суммировать все веса на родительском макете). На дочернем представлении укажите вес, который вы хотите, чтобы он взял. не забудьте указать

android:layout_width="0dp" 

пример

    <LinearLayout
                android:layout_width="500dp"
                android:layout_height="20dp" >

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="3"
                    android:background="@android:color/holo_green_light"
                    android:gravity="center"
                    android:text="30%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="2"
                    android:background="@android:color/holo_blue_bright"
                    android:gravity="center"
                    android:text="20%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="5"
                    android:background="@android:color/holo_orange_dark"
                    android:gravity="center"
                    android:text="50%"
                    android:textColor="@android:color/white" >
                </TextView>
 </LinearLayout>

это будет выглядеть как

enter image description here

если не указано, сумма вычисляется путем добавления layout_weight всех дочерних элементов. Это можно использовать, например, чтобы дать одному ребенку 50% от общего доступного пространства, предоставив ему layout_weight 0,5 и установив weightSum на 1,0. Должно быть значение с плавающей запятой, например "1.2"

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/main_rel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:weightSum="2.0" >

        <RelativeLayout
            android:id="@+id/child_one"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#0000FF" >
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/child_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#00FF00" >
        </RelativeLayout>

    </LinearLayout>

одна вещь, которая кажется, что никто больше не упоминал: допустим, у вас есть вертикальныйLinearLayout, поэтому для того, чтобы веса в макете / элементе / представлении внутри него работали на 100% правильно - все они должны иметь layout_height свойство (которое должно существовать в вашем xml-файле) установлено в 0dp. Кажется, что любое другое значение будет испортить вещи в некоторых случаях.

от застройщика документация

Это может быть использовано, например, чтобы дать один ребенок 50% из общего доступного пространства, давая ему layout_weight 0.5 и установка weightSum в 1.0.

дополнение к @ Shubhayu ответ

остальное 3/5 может использоваться для других дочерних макетов, которые действительно не нуждаются в какой-либо конкретной части, содержащей макет.

это потенциальное использование android:weightSum собственность.

вес макета работает как соотношение.весовая сумма делит всю компоновку на определенные части. и вес макета определяет, сколько часть делает конкретный элемент занимает из общей суммы веса заранее определенного. вес сумма может быть вручную, а также. Кнопки, текстовые представления, edittexts и т. д. Все они организованы с использованием weightsum и веса макета при использовании линейных макетов для дизайна пользовательского интерфейса.