¿Qué significa android: layout_weight?

Respuestas:

860

Con layout_weightusted puede especificar una relación de tamaño entre múltiples vistas. Por ejemplo, tiene un MapViewy un tableque debería mostrar información adicional al mapa. El mapa debe usar 3/4 de la pantalla y la tabla debe usar 1/4 de la pantalla. Luego establecerá el layout_weightde mapa 3 y el layout_weightde tablea 1.

Para que funcione, también debe establecer la altura o el ancho (según su orientación) en 0px.

Flo
fuente
208
¡rascador de cabeza hasta que hayas mencionado la altura de 0px!
JohnnyLambada
24
Para definir cuál de ellos se verá afectado por el peso. Ancho o alto.
neteinstein
30
Necesitas el 0px. Ejemplo: desea implementar una tabla con dos columnas de igual tamaño. Cada fila de la tabla es un diseño lineal horizontal con dos "celdas de tabla" (por ejemplo, TextViews), cada una de las cuales tiene layout_weight = .5. Si especifica layout_width = "wrap_content" en las "celdas de la tabla", el ancho del contenido se agregará al ancho calculado por layout_weight, las celdas de la tabla serán de diferentes tamaños y las columnas no se alinearán correctamente. Por lo tanto, debe establecer layout_width = 0dp para que Android solo use layout_weight para calcular el ancho de las celdas.
eeeeaaii
3
@Solace, respuesta tardía, pero por completo ... Parece que el atributo de peso no está contribuyendo a RelativeLayout. Solo funciona con LinearLayout. Si ve una necesidad de peso, quizás el camino a seguir es crear un LinearLayout (con ponderaciones) dentro de RelativeLayout.
bbv
1
¿layout_weight solo funciona para el diseño lineal o funcionará para todos los grupos de vistas?
meShakti
247

En pocas palabras, layout_weightespecifica cuánto espacio extra en el diseño se asignará a la Vista.

LinearLayout admite la asignación de un peso a niños individuales. Este atributo asigna un valor de "importancia" a una vista y le permite expandirse para llenar cualquier espacio restante en la vista principal. El peso predeterminado de las vistas es cero.

Cálculo para asignar cualquier espacio restante entre el niño

En general, la fórmula es:

espacio asignado al niño = (peso individual del niño) / (suma del peso de cada niño en Diseño lineal)

Ejemplo 1

Si hay tres cuadros de texto y dos de ellos declaran un peso de 1, mientras que al tercero no se le asigna peso (0), el espacio restante se asigna de la siguiente manera:

1er cuadro de texto = 1 / (1 + 1 + 0)

Segundo cuadro de texto = 1 / (1 + 1 + 0)

3er cuadro de texto = 0 / (1 + 1 + 0)

Ejemplo 2

Digamos que tenemos una etiqueta de texto y dos elementos de edición de texto en una fila horizontal. La etiqueta no se ha layout_weightespecificado, por lo que ocupa el espacio mínimo requerido para renderizar. Si el valor layout_weightde cada uno de los dos elementos de edición de texto se establece en 1, el ancho restante en el diseño principal se dividirá en partes iguales entre ellos (porque afirmamos que son igualmente importantes).

Cálculo:

Primera etiqueta = 0 / (0 + 1 + 1)

Segundo cuadro de texto = 1 / (0 + 1 + 1)

3er cuadro de texto = 1 / (0 + 1 + 1)

Si, en cambio, el primer cuadro de texto tiene un layout_weight1, y el segundo cuadro de texto tiene un layout_weight2, entonces un tercio del espacio restante se asignará al primero y dos tercios al segundo (porque reclamamos el segundo uno es más importante).

Cálculo:

Primera etiqueta = 0 / (0 + 1 + 2)

Segundo cuadro de texto = 1 / (0 + 1 + 2)

3er cuadro de texto = 2 / (0 + 1 + 2)


Artículo fuente

Arca
fuente
19
Una explicación mucho mejor que la respuesta seleccionada actualmente.
Sombra
12
Bueno, está la explicación simple (que aprecio) y los detalles esenciales (que aprecio de una manera diferente). Ambas son buenas respuestas.
cbmanica
3
Como se mencionó en otra parte, android:layout_width="0px"es importante. Además, los pesos no necesitan ser enteros.
Brian White el
Esto es un poco más difícil de entender que la respuesta seleccionada, pero proporciona la respuesta completa, especialmente cuando algunas vistas tienen peso y otras no. Ese es un gran caso de uso no cubierto por la respuesta seleccionada.
Acey
¿De dónde weightSumviene la imagen entonces? ¿Tiene algo que ver con layout_weight?
eRaisedToX
72

Además de las otras respuestas, lo más importante para que esto funcione es establecer el ancho de diseño (o altura) en 0px

android:layout_width="0px"

de lo contrario verás basura

roetzi
fuente
Creo que depende de si desea ocultar las vistas que no definen sus pesos o si desea mostrarlas con un tamaño que se ajuste al tamaño y dejar el espacio libre restante para las vistas "ponderadas".
Andrea Leganza
¿Qué sucede si necesito configurar el peso horizontal y vertical?
Alston
40

Si hay varias vistas que abarcan a LinearLayout, entonces layout_weightles da a cada una un tamaño proporcional. Una vista con un layout_weightvalor mayor "pesa" más, por lo que obtiene un espacio más grande.

Aquí hay una imagen para aclarar las cosas.

ingrese la descripción de la imagen aquí

Teoría

El término ponderación de diseño está relacionado con el concepto de promedio ponderado en matemáticas. Es como en una clase universitaria donde la tarea vale el 30%, la asistencia vale el 10%, la mitad del período vale el 20% y la final vale el 40%. Sus puntajes para esas partes, cuando se ponderan juntos, le dan su calificación total.

ingrese la descripción de la imagen aquí

Es lo mismo para el peso del diseño. En Viewshorizontal LinearLayout, cada uno puede ocupar un cierto porcentaje del ancho total. (O un porcentaje de la altura para una vertical LinearLayout).

El diseño

El LinearLayoutque uses se verá así:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <!-- list of subviews -->

</LinearLayout>

Tenga en cuenta que debe usar layout_width="match_parent"para LinearLayout. Si lo usas wrap_content, entonces no funcionará. También tenga en cuenta que layout_weightno funciona para las vistas en RelativeLayouts (vea aquí y aquí las respuestas SO que tratan este problema).

Las vistas

Cada vista en horizontal se LinearLayoutve más o menos así:

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

Tenga en cuenta que debe usar layout_width="0dp"junto con layout_weight="1". Olvidar esto causa muchos problemas de nuevos usuarios. (Consulte este artículo para obtener diferentes resultados que puede obtener al no establecer el ancho en 0.) Si sus vistas están en vertical, LinearLayout entonces layout_height="0dp", por supuesto, las usaría .

En el Buttonejemplo anterior establecí el peso en 1, pero puede usar cualquier número. Es solo el total lo que importa. Puede ver en las tres filas de botones en la primera imagen que publiqué, los números son todos diferentes, pero como las proporciones son las mismas, los anchos ponderados no cambian en cada fila. A algunas personas les gusta usar números decimales que tienen una suma de 1 para que en un diseño complejo quede claro cuál es el peso de cada parte.

Una nota final. Si tiene muchos diseños anidados que usan layout_weight, puede ser malo para el rendimiento.

Extra

Aquí está el diseño xml para la imagen superior:

<?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>
Suragch
fuente
1
Siempre me pregunto por qué más personas no publican imágenes para acompañar su XML. Es mucho más fácil entender las imágenes que el código.
AleksandrH
30

layout_weightle dice a Android cómo distribuir su Viewcorreo electrónico en a LinearLayout. Luego, Android calcula primero la proporción total requerida para todos Viewlos correos electrónicos que tienen un peso especificado y los coloca de Viewacuerdo con la fracción de pantalla que ha especificado que necesita. En el siguiente ejemplo, Android ve que los TextViews tienen un layout_weightde 0(este es el valor predeterminado) y los EditTexts tienen un layout_weightde 2cada uno, mientras que el Buttontiene un peso de 1. Por lo tanto, Android asigna "suficiente" espacio para mostrar tvUsernamey tvPasswordluego divide el resto del ancho de la pantalla en 5 partes iguales, dos de las cuales se asignan aetUsername , dos a etPasswordla última parte y a 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>

Se parece a:
orientación horizontal y
Orientación Vertical

Tash Pemhiwa
fuente
El enlace ya no está disponible. Si tiene otra buena referencia, actualice.
BinaryGuy
16

Piénsalo de esa manera, será más simple

Si tiene 3 botones y sus pesos son 1,3,1 en consecuencia, funcionará como una tabla en HTML

Proporcione 5 porciones para esa línea: 1 porción para el botón 1, 3 porciones para el botón 2 y 1 porción para el botón 1

Considerar,

George Nguyen
fuente
10

Una de las mejores explicaciones para mí fue esta (del tutorial de Android, busque el paso 7) :

layout_weight se usa en LinearLayouts para asignar "importancia" a las Vistas dentro del diseño. Todas las vistas tienen un diseño_peso predeterminado de cero, lo que significa que solo ocupan tanto espacio en la pantalla como sea necesario mostrar. Asignar un valor superior a cero dividirá el resto del espacio disponible en la Vista principal, de acuerdo con el valor del diseño de peso de cada Vista y su relación con el peso de diseño general especificado en el diseño actual para este y otros elementos de Vista.

Para dar un ejemplo: supongamos que tenemos una etiqueta de texto y dos elementos de edición de texto en una fila horizontal. La etiqueta no tiene un layout_weight especificado, por lo que ocupa el espacio mínimo requerido para renderizar. Si el diseño_peso de cada uno de los dos elementos de edición de texto se establece en 1, el ancho restante en el diseño principal se dividirá en partes iguales entre ellos (porque afirmamos que son igualmente importantes). Si el primero tiene un layout_weight de 1 y el segundo tiene un layout_weight de 2, entonces un tercio del espacio restante se asignará al primero y dos tercios al segundo (porque afirmamos que el segundo es más importante).

Andre Steingress
fuente
4

Para adicional

Para verticalorientarse, no olvide establecer heighten 0dp

android:layout_height="0dp"

Para horizontalorientarse, no olvide establecer widthen 0dp

android:layout_width="0dp"
Alen Lee
fuente
3

Mire el weightSum de LinearLayout y el layout_weight de cada vista. android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" Su layout_height son ambos 0px, pero no estoy seguro de que sea relevante

<?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>
Ming Leung
fuente
Mire el weightSum de LinearLayout y el layout_weight de cada vista. android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" Su layout_height son ambos 0px, pero no estoy seguro de que sea relevante.
Ming Leung
0

Combinando ambas respuestas de

Flo & rptwsthi y roetzi,

Recuerde cambiar su layout_width=0dp/px, de lo contrario, el layout_weightcomportamiento actuará de manera inversa con el número más grande ocupado en el espacio más pequeño y el número más bajo ocupado en el espacio más grande.

Además, algunas combinaciones de pesos provocarán que no se pueda mostrar un diseño (ya que ocupaba demasiado el espacio).

Cuidado con esto.

usuario2837483
fuente
0

Agregar android:autoSizeTextType="uniform"cambiará el tamaño del texto automáticamente

skryshtafovych
fuente
-1

Como su nombre lo indica, el peso del diseño especifica qué cantidad o porcentaje de espacio debe ocupar un campo o widget en particular en el espacio de la pantalla.
Si especificamos el peso en orientación horizontal, entonces debemos especificar layout_width = 0px.
Del mismo modo, si especificamos el peso en orientación vertical, entonces debemos especificar layout_height = 0px.

Akanksha Hegde
fuente