O que significa android: layout_weight?

Respostas:

860

Com layout_weightvocê pode especificar uma proporção de tamanho entre várias visualizações. Por exemplo, você tem um MapViewe um tableque deve mostrar algumas informações adicionais ao mapa. O mapa deve usar 3/4 da tela e a tabela deve usar 1/4 da tela. Então você definirá o layout_weightde map3 e o layout_weightde table1.

Para fazê-lo funcionar, você também deve definir a altura ou largura (dependendo da sua orientação) para 0px.

Flo
fonte
208
raspador de cabeça até você mencionar a altura de 0px!
JohnnyLambada
24
Definir qual deles será afetado pelo peso. Largura ou altura.
Neteinstein
30
Você precisa do 0px. Exemplo: você deseja implementar uma tabela com duas colunas do mesmo tamanho. Cada linha da tabela é um layout linear horizontal com duas "células da tabela" (por exemplo, TextViews), cada uma com layout_weight = 0,5. Se você especificar layout_width = "wrap_content" nas "células da tabela", a largura do conteúdo será adicionada à largura calculada por layout_weight, as células da tabela terão tamanhos diferentes e as colunas não serão alinhadas corretamente. Então você precisa definir layout_width = 0dp para que o Android use apenas layout_weight para calcular a largura das células.
eeeeaaii
3
@ Solace, resposta tardia, mas por uma questão de integridade. Parece que o atributo de peso não está contribuindo para o RelativeLayout. Funciona apenas com LinearLayout. Se houver necessidade de peso, talvez o caminho a seguir seja criar um LinearLayout (com pesos) no RelativeLayout.
bbv
1
layout_weight funciona apenas para o layout linear ou para todos os grupos de visualizações.
meShakti
247

Em poucas palavras, layout_weightespecifica quanto do espaço extra no layout deve ser alocado para a Visualização.

O LinearLayout suporta a atribuição de um peso a filhos individuais. Este atributo atribui um valor de "importância" a uma visualização e permite a expansão para preencher qualquer espaço restante na visualização pai. O peso padrão das visualizações é zero.

Cálculo para atribuir qualquer espaço restante entre filho

Em geral, a fórmula é:

espaço atribuído à criança = (peso individual da criança) / (soma do peso de cada criança no Layout Linear)

Exemplo 1

Se houver três caixas de texto e duas declararem peso 1, enquanto o terceiro não tiver peso (0), o espaço restante será atribuído da seguinte maneira:

1a caixa de texto = 1 / (1 + 1 + 0)

2ª caixa de texto = 1 / (1 + 1 + 0)

Terceira caixa de texto = 0 / (1 + 1 + 0)

Exemplo 2

Digamos que temos um rótulo de texto e dois elementos de edição de texto em uma linha horizontal. O rótulo não foi layout_weightespecificado, portanto, ocupa o espaço mínimo necessário para renderizar. Se layout_weightcada um dos dois elementos de edição de texto estiver definido como 1, a largura restante no layout pai será dividida igualmente entre eles (porque alegamos que são igualmente importantes).

Cálculo:

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

2ª caixa de texto = 1 / (0 + 1 + 1)

Terceira caixa de texto = 1 / (0 + 1 + 1)

Se, em vez disso, a primeira caixa de texto tiver um layout_weightde 1 e a segunda caixa de texto tiver um layout_weightde 2, um terço do espaço restante será atribuído à primeira e dois terços ao segundo (porque reivindicamos a segunda um é mais importante).

Cálculo:

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

2ª caixa de texto = 1 / (0 + 1 + 2)

Terceira caixa de texto = 2 / (0 + 1 + 2)


Artigo fonte

Arca
fonte
19
Uma explicação muito melhor do que a resposta atualmente selecionada.
Shade
12
Bem, há a explicação simples (que eu aprecio) e os detalhes detalhados (que eu aprecio de uma maneira diferente). Ambas são boas respostas.
Cbmanica 12/08
3
Como mencionado em outro lugar, android:layout_width="0px"é importante. Além disso, os pesos não precisam ser inteiros.
Brian White
Isso é um pouco mais difícil de entender do que a resposta selecionada, mas fornece a resposta completa - principalmente quando algumas visualizações têm pesos e outras não. Esse é um grande caso de uso não coberto pela resposta selecionada.
Acey
de onde weightSumvem a imagem então? Tem algo a ver com isso layout_weight?
eRaisedToX
72

adicionando às outras respostas, a coisa mais importante para que isso funcione é definir a largura (ou altura) do layout como 0px

android:layout_width="0px"

caso contrário, você verá lixo

roetzi
fonte
Eu acho que depende se você deseja ocultar visualizações que não definem seus pesos ou deseja mostrá-las com tamanho adequado e deixar o espaço livre restante para as visualizações "ponderadas".
Andrea Leganza 13/09/17
E se eu precisar configurar o peso horizontal e vertical?
Alston
40

Se houver várias visualizações abrangendo a LinearLayout, layout_weightdê a cada uma delas um tamanho proporcional. Uma visualização com um layout_weightvalor maior "pesa" mais, ficando com um espaço maior.

Aqui está uma imagem para tornar as coisas mais claras.

insira a descrição da imagem aqui

Teoria

O termo peso do layout está relacionado ao conceito de média ponderada em matemática. É como em uma aula de faculdade, onde a lição de casa vale 30%, a frequência vale 10%, o meio termo vale 20% e a final vale 40%. Suas pontuações nessas partes, quando ponderadas juntas, dão a você a nota total.

insira a descrição da imagem aqui

É o mesmo para o peso do layout. O Viewsnuma posição horizontal LinearLayoutpode tomar-se cada uma certa percentagem da largura total. (Ou uma porcentagem da altura para uma vertical LinearLayout.)

O layout

O LinearLayoutque você usar será mais ou menos assim:

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

    <!-- list of subviews -->

</LinearLayout>

Observe que você deve usar layout_width="match_parent"para o LinearLayout. Se você usar wrap_content, não funcionará. Observe também que layout_weightnão funciona para as visualizações em RelativeLayouts (consulte aqui e aqui as respostas para SO que lidam com esse problema).

As visualizações

Cada visualização em uma horizontal LinearLayouté mais ou menos assim:

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

Observe que você precisa usar layout_width="0dp"junto com layout_weight="1". Esquecer isso causa muitos problemas para novos usuários. (Consulte este artigo para obter resultados diferentes, não é possível definir a largura como 0.) Se suas visualizações estiverem na vertical LinearLayout , você usaria layout_height="0dp", é claro.

No Buttonexemplo acima, defino o peso como 1, mas você pode usar qualquer número. É apenas o total que importa. Você pode ver nas três linhas de botões na primeira imagem que eu publiquei, os números são todos diferentes, mas como as proporções são as mesmas, as larguras ponderadas não mudam em cada linha. Algumas pessoas gostam de usar números decimais com uma soma de 1, de modo que, em um layout complexo, fique claro qual é o peso de cada parte.

Uma nota final. Se você tiver muitos layouts aninhados em uso layout_weight, isso pode prejudicar o desempenho.

Extra

Aqui está o layout xml para a imagem 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
fonte
1
Eu sempre me pergunto por que mais pessoas não postam imagens para acompanhar seu XML. É muito mais fácil entender o visual do que o código.
AleksandrH
30

layout_weightdiz ao Android como distribuir seus Views em um LinearLayout. O Android primeiro calcula a proporção total necessária para todos os Views com um peso especificado e coloca cada um de Viewacordo com a fração da tela que ele especificou. No exemplo a seguir, o Android vê que os TextViews têm um layout_weightde 0(esse é o padrão) e os EditTexts têm um layout_weightde 2cada, enquanto o Buttonpeso é de 1. Portanto, o Android aloca espaço "apenas o suficiente" para exibir tvUsernamee, em tvPasswordseguida, divide o restante da largura da tela em 5 partes iguais, duas das quais são alocadas etUsername, duas etPassworde a última parte para 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>

Parece que:
orientação paisagem e
orientação retrato

Tash Pemhiwa
fonte
O link não está mais disponível. Se você tiver outra boa referência, atualize.
BinaryGuy
16

Pense assim, será mais simples

Se você tiver 3 botões e o peso deles for 1,3,1 em conformidade, funcionará como a tabela em HTML

Forneça 5 partes para essa linha: 1 parte para o botão 1, 3 partes para o botão 2 e 1 parte para o botão 1

Que diz respeito,

George Nguyen
fonte
10

uma das melhores explicações para mim foi esta (no tutorial do Android, procure a etapa 7) :

layout_weight é usado no LinearLayouts para atribuir "importância" às Views no layout. Todas as visualizações têm um layout_weight padrão de zero, o que significa que ocupam apenas o espaço na tela necessário para serem exibidas. A atribuição de um valor maior que zero dividirá o restante do espaço disponível na Visualização pai, de acordo com o valor do layout_weight de cada Visualização e sua proporção com o layout_weight geral especificado no layout atual especificado para esse e outros elementos da Visualização.

Para dar um exemplo: digamos que temos um rótulo de texto e dois elementos de edição de texto em uma linha horizontal. O rótulo não possui layout_weight especificado, portanto, ocupa o espaço mínimo necessário para renderizar. Se o layout_weight de cada um dos dois elementos de edição de texto estiver definido como 1, a largura restante no layout pai será dividida igualmente entre eles (porque alegamos que são igualmente importantes). Se o primeiro tiver um layout_weight de 1 e o segundo um layout_weight de 2, um terço do espaço restante será atribuído ao primeiro e dois terços ao segundo (porque afirmamos que o segundo é mais importante).

Andre Steingress
fonte
4

Para adicional :

Para verticalorientação, não se esqueça de definir height0dp

android:layout_height="0dp"

Para horizontalorientação, não se esqueça de definir width0dp

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

Veja a weightSum de LinearLayout e o layout_weight de cada View. android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" O layout_height são ambos 0px, mas não tenho certeza se é 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
fonte
Veja a weightSum de LinearLayout e o layout_weight de cada View. android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" O layout_height são ambos 0px, mas não tenho certeza se é relevante.
Ming Leung
0

Combinando as duas respostas de

Flo & rptwsthi e roetzi,

Lembre-se de mudar o seu layout_width=0dp/px, caso contrário, o layout_weightcomportamento agirá inversamente com o maior número ocupado no menor espaço e o menor número ocupado no maior espaço.

Além disso, algumas combinações de pesos farão com que alguns layouts não sejam mostrados (uma vez que ocuparam demais o espaço).

Cuidado com isso.

user2837483
fonte
0

Adicionar android:autoSizeTextType="uniform"irá redimensionar o texto automaticamente

skryshtafovych
fonte
-1

Como o nome sugere, a espessura do layout especifica qual quantidade ou porcentagem de espaço que um campo ou widget específico deve ocupar no espaço da tela.
Se especificarmos o peso na orientação horizontal, devemos especificar layout_width = 0px.
Da mesma forma, se especificarmos o peso na orientação vertical, devemos especificar layout_height = 0px.

Akanksha Hegde
fonte