Usando styles nos layouts da sua aplicação Android

Construir layouts no Android não é uma tarefa fácil e exige bastante esforço. Não só pela fragmentação, mas também pela orientação e outros detalhes. Digamos que estamos construindo uma aplicação que terá dois layouts diferentes. Um para quando o dispositivo estiver com a tela em portrait e outro para quando o dispositivo estiver com a tela em landscape. Podemos resolver esse problema usando o Application Resources. Basta criarmos um main.xml na pasta layout e outro main.xml na pasta layout-land. Vamos começar com o portrait:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
      <TextView android:layout_height="0dp" android:layout_weight="1"
         android:gravity="center" android:layout_width="match_parent"
         android:text="Esse é o texto número um" />
      <TextView android:layout_height="0dp" android:layout_weight="1"
         android:gravity="center" android:layout_width="match_parent"
         android:text="Esse é o texto número Dois" />
</LinearLayout>

Já em landscape (dentro de res/layout-land), teremos android:orientation="horizontal" além da diferença de pesos entre largura e altura:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
   <TextView android:layout_height="match_parent" android:layout_weight="1"
       android:gravity="center" android:layout_width="0dp"
       android:text="Esse é o texto número um" />
   <TextView android:layout_height="match_parent" android:layout_weight="1"
       android:gravity="center" android:layout_width="0dp"
       android:text="Esse é o texto número Dois" />
</LinearLayout>

Os resultados serão:

Se não tivessemos criado um main.xml dentro de res/layout-land, em landscape nossa tela apresentaria as duas mensagens uma em cima da outra, aproveitando mal o espaço nesse caso. Ainda assim, temos alguns problemas técnicos, em especial ter de possuir dois main.xml diferentes, com muito código igual em seus interiores. Se tivermos de mudar o layout, teremos de alterar os dois arquivos.

Poderíamos agrupar o que for comum entre os layout, nos poupando de retrabalhos futuros. Para realizarmos o agrupamento de informações do layout, usamos o resource Style. Vamos criar, dentro da pasta res/values, um arquivo styles.xml. Dentro dele podemos ter os chamados “estilos” de cada tipo de componente, neste caso para o dispositivo em portrait:

<?xml version="1.0" encoding="utf-8"?>
<resources>
     <style name="Orientation">
          <item name="android:orientation">vertical</item>
     </style>
     <style name="TextStyle">
          <item name="android:layout_weight">1</item>
          <item name="android:gravity">center</item>
    </style>
    <style name="TextWidth" parent="TextStyle">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">@dimen/zero</item>
    </style>
</resources>

Aqui definimos o estilo para o LinearLayout, que no caso de portrait será vertical. Para detalhes de apresentação de texto, definimos o peso e o gravity em um estilo chamado TextStyle (esse nome é arbitrário) e o outro, nomeado TextWidth, com o tamanho do campo. Repare no TextWidth que usamos a tag parent. Fazemos isso para poder reaproveitar estilos em outros estilos, e nesse caso quem utilizar TextWidth terá também os atributos declarados em TextStyle.

Para usarmos esses styles que acabamos de definir, basta aplicar a tag style dentro de nosso layout, como por exemplo style=@style/TextWidth. Veja como ficou nosso main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/Orientation"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <TextView style="@style/TextWidth" android:text="@string/textOne" />
    <TextView style="@style/TextWidth" android:text="@string/textTwo" />
</LinearLayout>

Repare que além de colocarmos os styles, nós também colocamos os textos e dimensões em arquivos strings.xml e dimens.xml. Estamos seguindo a convenção definida pelo Android de que dimenões e textos devem estar externalizados em seus respectivos arquivos. A ferramenta lint pode te ajudar bastante a achar o que ainda não foi externalizado na sua aplicação.

Ainda temos dois arquivos main.xml, um está na pasta res/layout e outro na res/layout-land. Vamos apagar toda a pasta layout-land. Teremos apenas o arquivo main.xml na pasta res/layout. Agora vamos criar uma pasta chamada res/values-land. Dentro dessa pasta vamos criar um arquivo styles.xml.

Dentro do arquivo styles.xml vamos alterar os estilos que precisamos mudar, no nosso caso a orientação do linear e o tamanho dos TextVieẁs. Para isso, criamos o arquivo style.xml da pasta res/values-land.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Orientation">
        <item name="android:orientation">horizontal</item>
    </style>
    <style name="TextWidth" parent="TextStyle">
        <item name="android:layout_width">@dimen/zero</item>
        <item name="android:layout_height">match_parent</item>
    </style>
</resources>

Você deve está se perguntando o porquê de não declararmos TextStyle nesse arquivo. Não precisamos escrever o TextStyle por que ele já foi declarado na pasta values default. Quando ele não encontra o style de TextStyle no res/values-land, ele vai procurar no arquivo style.xml declarado na pasta default, isso é, res/values. Agora sim, temos apenas um arquivo main.xml. Customizações do nosso layout ficam então definidos em arquivos de styles.

O código deste teste está disponível no github. Não deixe de conhecer nosso curso completo de desenvolvimento Android.

9 Comentários

  1. Flavio Sakamura 22/03/2012 at 19:09 #

    Excelente! mas pra ficar bom vai sempre dar trabalho, com os styles ou não.

  2. Fabio Licks 28/03/2012 at 11:13 #

    Muito interessante! No entanto faz parecer que não é necessário definir layout diferentes, que basta definir estilos diferentes para o mesmo layout. O que nem sempre é verdade.

    De toda forma, muito bom trabalho!

  3. Gean 06/02/2013 at 10:41 #

    Estou fazendo uma aplicação, mas quando ensiro o TextView, EditText e Button, na tela do emulador fica um em cima do outro como resolver?

  4. André Silva 06/02/2013 at 17:57 #

    Gean,

    Muito provavelmente que você está usando um relative layout.

  5. Guilherme berghauser 07/02/2013 at 14:58 #

    Muito bom o post, ajudou muito 😀

  6. Ronaldo 25/04/2013 at 14:39 #

    Fiz exatamente que está ai porem quando digito algo no TextView e mudo de orientação ele apaga os dados, existe alguma forma de arrumar isso?

  7. Daniel 05/05/2013 at 22:07 #

    Ronaldo, coloque isso no seu Manifest.xml.

  8. Lucas 26/04/2015 at 14:53 #

    Interessante! Com isso consigo uma otima organização de cores e muito mais, valeu por disponibilizar essas técnicas….. mais o que estava procurando e como adicionar arquivos .smali ( CSS em app )

Deixe uma resposta