Що таке андроїд: weightSum в android, і як це працює?


Відповіді:


133

За документацією 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 корисно для правильного відображення макета для будь-якого пристрою, що не відбудеться, якщо встановити ширину та висоту безпосередньо.


145
Це не пояснення мети weightSum. Поведінка у вашому прикладі буде ідентичною weightSumопущеній, і насправді weightSum не повинен бути вказаний у цьому сценарії. Документація каже,weightSum Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children.
Джефф Аксельрода

3
@JeffAxelrod: Це "не слід" вказувати? Чому? Я не бачу причин для цього. Тому я просто сказав, що цього не потрібно вказувати.
каре

17
@MarcoW. Це не повинно бути вказано через ремонтопридатність. Як сказав Джефф, встановлення weightSum дорівнює сумі ваг всередині макета нічого не приводить, але якщо хтось змінить його в майбутньому, це може спричинити головні болі, оскільки зараз є непотрібний модифікатор макета, який потрібно було б знайти і змінився. Ця відповідь невірна і не повинна бути прийнятою відповіддю.
d370urn3ur

3
Не бачте хорошого пояснення параметра weightSum, тому в документах: "Це можна використовувати, наприклад, для того, щоб дати одній дитині 50% від загального доступного простору, надавши макет-вага 0,5 і встановивши weightSum до 1,0". Дивіться developer.android.com/reference/android/widget/…
Deepscorn

5
Ідея полягає в тому, що ви можете встановити weightSum на число, що перевищує суму дітей. Це призводить до того, що діти отримують деякий, але не весь наявний додатковий простір. У наведеному вище прикладі ваша одинока дитина успадкувала б половину наявного місця замість всього.
Едвард Фолк

175

Додавши до відповіді суперМами та Джеффа,

Якщо в LinearLayout є 2 перегляди, перший з макетом-вагою 1, другий з макетом_ вагою 2 і не вказано weightSum, за замовчуванням weightSum обчислюється як 3 (сума ваг дітей) і перший погляд займає 1/3 місця, а другий 2/3.

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


2
Я шукав те саме, що робити, якщо вагова сума не визначена і ваги будуть надані дитячим уявленням. Ваша відповідь, що вона обчислює власне все очищене
DeltaCap019

Чи правда, що рекомендується використовувати RelativeLayout, ніж макети з weightSum?
Роберт

26

Сума ваги працює саме так, як ви хочете (як і інші відповіді, вам не потрібно підсумовувати всі ваги на батьківському макеті). На дитячому перегляді вкажіть вагу, яку ви бажаєте набрати. Не забудьте вказати

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>

Це буде виглядати приблизно так

введіть тут опис зображення


25

Документація каже , що краще , і включає в себе приклад, (підсвічування шахти).

android: weightSum

Визначає максимальну вагову суму. Якщо не визначено, сума обчислюється шляхом додавання макет_ ваги всіх дітей. Це може бути використано, наприклад, для того, щоб дати одній дитині 50% всього наявного простору, надавши їй масу ваги 0,5 і встановивши weightSum до 1,0.

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

Для цього ви застосуєте layout_weight1 для кожного ImageView, жодного на TextView, а weightSum2,0 для LinearLayout.


20

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

Припустимо, що weightSumвстановлено значення. Справа відсутності обговорюється пізніше.

По-перше, розділіть на weightSumкількість елементів, з якими match_parentабо fill_parentв розмірності LinearLayout (наприклад, layout_widthдля orientation="horizontal"). Ми будемо називати це значення коефіцієнтом ваги ш_мдля кожного елемента. Значення за замовчуванням 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) * максимальне_можливе_розширення

Приклад:

Якщо 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елементи все одно можуть бути витіснені з видимої області елементами, вага яких менший мультиплікатор ваги(наприклад, між 0-1 для weightSum= 1 або між 0-20 для вищевказаного прикладу).

Якщо не weightSumвказано жодне , воно обчислюється як сума всіх layout_weightзначень, включаючи елементи з wrap_contentнабором! Отже, layout_weightвстановивши wrap_contentелементи, може вплинути на їх розширення. Наприклад, негативна вага зменшить інші fill_parentелементи. Перед тим, як fill_parentелементи будуть викладені, чи буде застосована вищезазначена формула до wrap_contentелементів, при цьому максимально можливим розширенням буде їх розширення відповідно до обгорнутого вмісту. Ці wrap_contentелементи будуть усадка, а потім максимально можливе розширення для решти fill_parentелементів обчислюються і розподілено.

Це може призвести до неінтуїтивних результатів.


10

Якщо не визначено, сума обчислюється шляхом додавання макет_ ваги всіх дітей. Це може бути використано, наприклад, для того, щоб дати одній дитині 50% всього наявного простору, надавши їй масу ваги 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>

"Може бути значенням з плаваючою комою, наприклад," 1,2 "." ( developer.android.com/reference/android/widget/… )
Неймовірний

6

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


1
android: layout_width = "match_parent" зазвичай використовується замість 0dp
kc ochibili

чому це так? Я маю на увазі, ви праві, що це заплуталося, але встановлення висоти 0 dp вирішило мою проблему. я хотів би знати причину.
Абдул Вахід

2

Вага макета працює як співвідношення. Наприклад, якщо є вертикальний макет і є два елементи (такі як кнопки або перегляд тексту), один має макет 2 і другий має макет 3 відповідно. Тоді 1-й елемент займе 2 з 5 частин екрана / макета, а інший 3 з 5 частин. Тут 5 - вагова сума. тобто сума ваги ділить весь макет на визначені частини. А Вага макета визначає, яку частку займає конкретний предмет із загальної попередньо визначеної суми ваги. Вагова сума також може бути оголошена вручну. Кнопки, перегляд тексту, редакційні тексти тощо - це впорядковано за допомогою вагової суми та ваги макета при використанні лінійних макетів для дизайну інтерфейсу.


1

З документації розробника

Це можна використовувати, наприклад, для надання єдиній дитині 50%загального доступного простору, надавши їй масу_ ваги 0.5та встановивши weightSum 1.0.

Доповнення до відповіді @Shubhayu

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

це потенційне використання android:weightSumмайна.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.