it-swarm.com.ru

Что такое Android: весовая сумма в Android и как она работает?

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

144
Dhiral Pandya

Согласно документации, 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 полезен для правильной визуализации макета для любого устройства, что не произойдет, если вы установите ширину и высоту напрямую.

114
superM

Добавление к ответам SuperM и Джеффа,

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

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

167
Shubhayu

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

Android: weightSum

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

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

Для этого вы должны применить layout_weight 1 к каждому ImageView, ни один для TextView, и weightSum 2,0 для LinearLayout.

23
Jeff Axelrod

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

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

22
asok Buzz

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

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

Сначала разделите weightSum на количество элементов с 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 <em loading=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! Поэтому, установив layout_weight для элементов wrap_content, can влияет на их расширение. Например. отрицательный вес сократит другие элементы fill_parent. Перед размещением элементов fill_parent будет ли приведенная выше формула применяться к элементам wrap_content, причем максимально возможным расширением будет их расширение в соответствии с упакованным содержимым. Элементы wrap_content будут сжаты, и после этого будет вычислено и распределено максимально возможное расширение для остальных элементов fill_parent.

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

19
Jens Jensen

Если не указано, сумма вычисляется путем добавления 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>
9
Faakhir

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

6
Yoav Feuerstein

Вес макета работает как отношение. Например, если есть вертикальный макет и есть два элемента (например, кнопки или текстовые представления), один из которых имеет вес макета 2, а другой имеет вес 3 макета соответственно. Тогда 1-й элемент будет занимать 2 из 5 частей экрана/макета, а другой - 3 из 5 частей. Здесь 5 - весовая сумма. то есть Весовая сумма делит весь макет на определенные части.И Вес макета определяет, какую часть занимает конкретный элемент из общей предварительно определенной суммы Веса. Сумма веса может быть также объявленным вручную. Кнопки, текстовые представления, edittexts и т.д. Все организованы с использованием веса и веса макета при использовании линейных макетов для дизайна пользовательского интерфейса.

1
Sami Al-Jabar

От разработчика документация

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

Дополнение к @Shubhayu ответу

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

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

1
DjP