que - ¿Qué es android: weightSum en Android, y cómo funciona?
android layout_weight (9)
Quiero saber: ¿Qué es android: weightSum y el peso del diseño, y cómo funcionan?
Agregando a la respuesta de superM y Jeff,
Si hay 2 vistas en LinearLayout, la primera con un layout_weight de 1, la segunda con un layout_weight de 2 y no weightSum está especificada, de forma predeterminada, weightSum se calcula que es 3 (suma de los pesos de los niños) y la primera vista toma 1/3 del espacio mientras que la segunda toma 2/3.
Sin embargo, si tuviéramos que especificar weightSum como 5, el primero tomaría 1 / 5th del espacio, mientras que el segundo tomaría 2 / 5th. Por lo tanto, un total de 3/5 del espacio estaría ocupado por el diseño, manteniendo el resto vacío.
De la documentation desarrollador
Esto se puede utilizar, por ejemplo, para dar a un niño el 50%
del espacio total disponible, dándole un diseño_peso de 0.5
y estableciendo el pesoSum en 1.0
.
Adición a @Shubhayu respuesta
El resto 3/5
se puede usar para otros diseños secundarios que realmente no necesitan una parte específica del diseño contenedor.
este es el uso potencial de la propiedad android:weightSum
.
Después de experimentar un poco, creo que el algoritmo para LinearLayout es este:
Suponga que weightSum
está establecido en un valor. El caso de la ausencia se discute más adelante.
Primero, divida el weightSum
por la cantidad de elementos con match_parent
o fill_parent
en la dimensión del LinearLayout (por ejemplo, layout_width
para orientation="horizontal"
). Llamaremos a este valor el multiplicador de peso para cada elemento. El valor predeterminado para weightSum
es 1.0, por lo que el multiplicador de peso predeterminado es 1/n
, donde n
es el número de elementos fill_parent
; wrap_content
elementos wrap_content
no contribuyen a n
.
Por ejemplo, cuando weightSum
es 60 y hay 3 elementos fill_parent
, el multiplicador de peso es 20. El multiplicador de peso es el valor predeterminado para, por ejemplo, layout_width
si el atributo está ausente.
En segundo lugar, se calcula la expansión máxima posible de cada elemento. En primer lugar, los elementos wrap_content
se calculan según sus contenidos. Su expansión se deduce de la expansión del contenedor padre. Llamaremos al manteiner expansion_remainer
. Este resto se distribuye entre elementos fill_parent
según su layout_weight
.
En tercer lugar, la expansión de cada elemento fill_parent
se calcula como:
Ejemplo:
Si weightSum
es 60 y hay 3 elementos fill_parent
con los pesos 10, 20 y 30, su expansión en la pantalla es 2/3, 1/3 y 0/3 del contenedor primario.
weight | expansion
0 | 3/3
10 | 2/3
20 | 1/3
30 | 0/3
40 | 0/3
La expansión mínima está limitada a 0. La expansión máxima está limitada al tamaño principal, es decir, los límites están limitados a 0.
Si un elemento se establece en wrap_content
, su expansión se calcula primero, y la expansión restante está sujeta a distribución entre los elementos fill_parent
. Si se establece weightSum
, esto conduce a layout_weight
sin efecto en los elementos de wrap_content
. Sin embargo, los elementos wrap_content
aún pueden ser expulsados del área visible por elementos cuyo peso sea menor que (por ejemplo, entre 0-1 para weightSum
= 1 o entre 0-20 para el ejemplo anterior).
Si no se especifica weightSum
, se calcula como la suma de todos los valores de layout_weight
, incluidos los elementos con el conjunto wrap_content
. Por lo tanto, tener layout_weight
establecido en los elementos wrap_content
puede influir en su expansión. Por ejemplo, un peso negativo reducirá los otros elementos fill_parent
. Antes de que se fill_parent
elementos fill_parent
, se aplicará la fórmula anterior a los elementos wrap_content
, con la expansión máxima posible siendo su expansión de acuerdo con el contenido envuelto. Los elementos wrap_content
reducirán y, a continuación, se calculará y distribuirá la máxima expansión posible para los elementos fill_parent
restantes.
Esto puede conducir a resultados poco intuitivos.
La documentation dice mejor e incluye un ejemplo (resaltando el mío).
android: weightSum
Define la suma de peso máxima. Si no se especifica, la suma se calcula sumando el layout_weight de todos los elementos secundarios. Esto se puede utilizar, por ejemplo, para dar a un niño el 50% del espacio total disponible, dándole un diseño_peso de 0.5 y estableciendo el pesoSum en 1.0.
Entonces, para corregir el ejemplo de superM, supongamos que tiene un LinearLayout
con orientación horizontal que contiene dos ImageViews
y un TextView
con. Usted define el TextView
para tener un tamaño fijo, y le gustaría que los dos ImageViews
ocupen el espacio restante por igual.
Para lograr esto, debe aplicar layout_weight
1 a cada ImageView
, ninguno en TextView
y un weightSum
de 2.0 en LinearLayout
.
La suma de peso funciona exactamente como lo desee (al igual que otras respuestas, no es necesario sumar todos los pesos en el diseño principal). En la vista infantil, especifique el peso que desea que tome. No te olvides de especificar
android:layout_width="0dp"
El siguiente es un ejemplo
<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>
Esto se verá
Si no se especifica, la suma se calcula sumando el layout_weight de todos los elementos secundarios. Esto se puede utilizar, por ejemplo, para dar a un niño el 50% del espacio total disponible, dándole un diseño_peso de 0.5 y estableciendo el pesoSum en 1.0. Debe ser un valor de coma flotante, como "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>
Una cosa que parece que nadie más mencionó: digamos que tiene un LinearLayout
vertical , por lo que para que los pesos en el diseño / elemento / vista dentro de él funcionen 100% correctamente, todos deben tener la propiedad layout_height
(que debe existir en su archivo xml) establecido en 0dp
. Parece que cualquier otro valor arruinaría las cosas en algunos casos.
El peso del diseño funciona como una proporción. Por ejemplo, si hay un diseño vertical y hay dos elementos (como botones o vistas de texto), uno con un peso de diseño 2 y otro con un peso de diseño de 3, respectivamente. Luego, el primer elemento ocupará 2 de cada 5 porciones de la pantalla / diseño y el otro 3 de 5 porciones. Aquí 5 es la suma de peso. es decir, Weight Sum divide el diseño completo en porciones definidas. Y el peso del diseño define la cantidad de porción que ocupa el artículo en particular de la suma de peso total predefinida. La suma de peso se puede declarar manualmente también. Los botones, textviews, edittexts, etc. están organizados utilizando pesos y peso de diseño cuando se utilizan diseños lineales para el diseño de la interfaz de usuario.
Según la documentación, android:weightSum
define la suma de peso máxima, y se calcula como la suma del layout_weight
de todos los hijos si no se especifica explícitamente.
Consideremos un ejemplo con LinearLayout
con orientación horizontal y 3 ImageViews
dentro de él. Ahora queremos que estas ImageViews
siempre tengan el mismo espacio. Para lograr esto, puede establecer el layout_weight
de cada ImageView
en 1 y se calcula que weightSum
será igual a 3 como se muestra en el comentario.
<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
es útil para hacer que el diseño se represente correctamente para cualquier dispositivo, lo que no sucederá si establece el ancho y la altura directamente.