segunda-feira, 24 de outubro de 2011

Android: utilizando layout_weight

Olá povo,

Em todas as minhas turmas de Android, noto uma certa dificuldade em entender como funciona a propriedade layout_weight utilizada nos componentes inseridos dentro do LinearLayout. Por padrão, essa propriedade serve para definir como o espaço restante do layout deve ser distribuído pelos componentes. Mas esse comportamento pode variar de acordo com o valor definido na propriedade layout_width e layout_height. Observemos a figura abaixo:




O layout acima é um LinearLayout vertical (orientation=vertical) com vários LinearLayout horizontal iguais, com 3 botões cada, e com os respectivos textos: "Um", "exemplo" e "de peso".

Vamos ver como da linha está configurada:

Linha1 - Nessa linha não fizemos nenhuma modificação, ou seja, está sem peso e com a largura e altura (layout_width e layout_height) definidos como wrap_content.
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<Button
android:text="Um"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="Exemplo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="de peso"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

Linha 2 - Nesse linha, definimos pesos iguais para todos os botões. Notem que apesar dos pesos estarem iguais, os componentes não têm tamanhos iguais. Essa é a aplicação clássica do layout_weight. Como vimos na linha 1, sobrou um espaço entre o terceiro botão e a margem direita. Com os pesos iguais, o espaço restante é distribuído igualmente entre os componentes. Uma vez que o texto de um botão é maior que o outro, os botões ficam com larguras diferentes.
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<Button
android:text="Um"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="Exemplo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="de peso"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>

Linha 3 - Essa linha é similar a anterior, a diferença fica por conta da propriedade layout_width definida como 0dp. Como assim? Se setarmos a largura para zero, o componente não deveria aparecer certo? A resposta é sim, mas como estamos usando o peso, ele vai distribuir o espaço restante da tela igualmente para os 3 botões. Como os 3 botões estão com tamanho zero, o espaço restante (e que será dividido entre os componentes) é toda a tela.
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<Button
android:text="Um"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="Exemplo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="de peso"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>

Linha 4 - Igual a anterior, mas modificamos a proporção dos componentes. Os dois primeiros ocupam metade da tela, e o terceiro ocupa a outra metade.
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<Button
android:text="Um"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="Exemplo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="de peso"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
</LinearLayout>

Linha 5 - Essa linha usa uma outra utilidade do layout_weight, a de prioridade. No código abaixo os dois primeiros botões estão com a propriedade layout_width setada para match_parent (que é o mesmo que fill_parent), ou seja, devem ocupar toda a largura do seu pai. Se esses componentes não tivessem o peso setado, o primeiro botão ocuparia toda a tela, e os demais não apareceriam. Uma vez que definimos o peso, cada um deles divide a tela, mas e o terceiro? Como não foi definido peso para ele, ele tem peso zero, então, o componente com MENOR peso, tem MAIOR prioridade, então ele passa a aparecer. Note que o layout_width do terceiro botão está como wrap_content, se estivesse fill_parent, ele ocuparia toda a tela, uma vez que ele tem peso menor (zero).
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<Button
android:text="Um"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="Exemplo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="de peso"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

Linha 6 - Conforme explicado acima, todos os botões estão com a propriedade layout_width definidos como fill_parent, entretanto, o primeiro está com peso 2, enquanto os demais tem peso 1. Logo os com peso menor tem prioridade.
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent">
<Button
android:text="Um"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="2"/>
<Button
android:text="Exemplo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:text="de peso"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>


Espero que agora fique mais claro a utilização do peso. Na dúvida, deixem seus comentários.

4br4ç05,
nglauber

3 comentários:

Vinicius disse...

ótima dica!!! obrigado !!! blog bookmarkado.. rsrsr

Mateus disse...

Exatamento o que eu estava procurando!!!

Obrigado.

Rogério disse...

Muito obrigado, era exatamente oque procurava!