Skip to content

Most visited

Recently visited

navigation

Suporte para diferentes tamanhos de tela

Esta lição mostra como oferecer suporte a diferentes tamanhos de tela:

Usar "wrap_content" e "match_parent"

Para garantir que o layout esteja flexível e adapte-se a diferentes tamanhos de tela, use "wrap_content" e "match_parent" para a largura e a altura de alguns componentes de exibição. Se usar "wrap_content", a largura ou a altura da exibição será definida para o tamanho mínimo necessário para encaixar o conteúdo dentro dessa exibição, enquanto que "match_parent" fará o componente ampliar para corresponder ao tamanho da exibição principal.

Ao usar os valores de tamanho "wrap_content" e "match_parent" em vez de tamanhos codificados, as exibições usam somente o espaço necessário para essa exibição ou expandem para preencher adequadamente o espaço disponível. Por exemplo:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout android:layout_width="match_parent" 
                  android:id="@+id/linearLayout1"  
                  android:gravity="center"
                  android:layout_height="50dp">
        <ImageView android:id="@+id/imageView1" 
                   android:layout_height="wrap_content"
                   android:layout_width="wrap_content"
                   android:src="@drawable/logo"
                   android:paddingRight="30dp"
                   android:layout_gravity="left"
                   android:layout_weight="0" />
        <View android:layout_height="wrap_content" 
              android:id="@+id/view1"
              android:layout_width="wrap_content"
              android:layout_weight="1" />
        <Button android:id="@+id/categorybutton"
                android:background="@drawable/button_bg"
                android:layout_height="match_parent"
                android:layout_weight="0"
                android:layout_width="120dp"
                style="@style/CategoryButtonStyle"/>
    </LinearLayout>

    <fragment android:id="@+id/headlines" 
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

Observe como o exemplo usa "wrap_content" e "match_parent" para tamanhos de componentes em vez de dimensões específicas. Isso permite que o layout se adapte corretamente a diferentes tamanhos e orientações de tela.

Por exemplo, é esta a aparência do layout nos modos retrato e paisagem. Observe que os tamanhos dos componentes se adaptam automaticamente à largura e à altura:

Figura 1. O aplicativo de exemplo News Reader no modo retrato (à esquerda) e paisagem (à direita).

Usar RelativeLayout

Você pode construir layouts relativamente complexos usando instâncias aninhadas de LinearLayout e combinações de tamanhos "wrap_content" e "match_parent". No entanto, LinearLayout não permite controlar precisamente as relações espaciais de exibições dependentes; exibições em um LinearLayout simplesmente se alinham lado a lado. Se você precisa que as exibições dependentes sejam orientadas em variações diferentes de uma linha reta, frequentemente uma solução melhor é usar um RelativeLayout, que permite especificar o layout em termos de relações espaciais entre componentes. Por exemplo, uma exibição secundária pode ser alinhada no lado esquerdo e outra, no lado direito da tela.

Por exemplo:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/label"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Type here:"/>
    <EditText
        android:id="@+id/entry"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/label"/>
    <Button
        android:id="@+id/ok"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/entry"
        android:layout_alignParentRight="true"
        android:layout_marginLeft="10dp"
        android:text="OK" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/ok"
        android:layout_alignTop="@id/ok"
        android:text="Cancel" />
</RelativeLayout>

A figura 2 mostra como esse layout aparece em uma tela QVGA.

Figura 2. Instantâneo em uma tela QVGA (tela pequena).

A figura 3 mostra como esse layout aparece em uma tela maior.

Figura 3. Instantâneo em uma tela WSVGA (tela grande).

Observe que, apesar do tamanho dos componentes ter mudado, as relações espaciais estão preservadas como especificado pelo RelativeLayout.LayoutParams.

Usar qualificadores de tamanho

Um layout flexível ou relativo tem suas limitações, como visto nas seções anteriores. Apesar de esses layouts se adaptarem a diferentes telas esticando o espaço dentro e em torno dos componentes, eles podem não oferecer a melhor experiência ao usuário para cada tamanho de tela. Portanto, o aplicativo não deve apenas implementar layouts flexíveis, mas também oferecer diferentes layouts alternativos direcionados a diversas configurações de tela. Faça isso usando qualificadores de configuração, que permitem que o tempo de execução selecione automaticamente o recurso adequado com base na configuração atual do dispositivo (como um projeto de layout diferente para distintos tamanhos de tela).

Por exemplo, diversos aplicativos implementam o padrão “painel duplo” para telas grandes (o aplicativo pode mostrar uma lista de itens em um painel e o conteúdo em outro). Tablets e TVs são grandes o suficiente para que os dois painéis se encaixem simultaneamente na tela, mas telas de telefone precisam mostrá-los separadamente. Portanto, para implementar esses layouts, você pode ter os seguintes arquivos:

Observe o qualificador large no nome do diretório do segundo layout. Esse layout será selecionado em dispositivos com telas classificadas como grandes (por exemplo, tablets com 7 pol e maiores ). O outro layout (sem qualificadores) será selecionado para dispositivos menores.

Usar o qualificador de menor largura

Uma das dificuldades dos desenvolvedores em dispositivos Android antes da versão 3.2 era a posição de tamanho de tela “grande" que abrange o Dell Streak, o Galaxy Tab original e tablets de 7 pol em geral. No entanto, muitos aplicativos podem querer mostrar diferentes layouts para diferentes dispositivos nesta categoria (como para dispositivos de 5 pol e 7 pol), mesmo sendo todos considerados telas “grandes”. É por isso que o Android introduziu o qualificador “menor largura" (entre outros) no Android 3.2.

O qualificador de menor largura permite direcionar telas com uma determinada largura fornecida em dp. Por exemplo, o tablet típico de 7 pol tem uma largura mínima de 600 dp, portanto, se você quiser que a interface do usuário tenha dois painéis nessas telas (mas uma única lista em telas menores), poderá usar os mesmos dois layouts da seção anterior para layouts com painel único e painel duplo, mas, em vez do qualificador de tamanho large, use sw600dp para indicar que o layout com painel duplo é para telas com largura máxima de 600 dp:

Isso significa que dispositivos cuja largura menor é maior ou igual a 600 dp selecionarão o layout layout-sw600dp/main.xml (painel duplo), enquanto que telas menores selecionarão o layout layout/main.xml (painel único) .

No entanto, isso não funciona em dispositivos antes do 3.2, pois eles não reconhecem sw600dp como qualificador de tamanho, de maneira que ainda será preciso usar o qualificador large . Portanto, você precisa de um arquivo de nome res/layout-large/main.xml idêntico a res/layout-sw600dp/main.xml. Na próxima seção, você verá uma técnica que permite evitar a duplicação de arquivos de layout dessa forma.

Usar aliases de layout

O qualificador de menor tamanho só está disponível no Android 3.2 e superior. Portanto, você deve usar localizadores de tamanho abstrato (pequeno, normal, grande e extra grande) para oferecer a compatibilidade com outras versões. Por exemplo, se quiser projetar a interface do usuário para mostrar uma interface com painel único em telefones, mas uma interface com vários painéis em tablets de 7 pol, TVs e outros dispositivos grandes, será preciso fornecer estes arquivos:

Os últimos dois arquivos são idênticos, pois um deles será correspondido por dispositivos Android 3.2 e o outro será usado em tablets e TVs com versões anteriores do Android.

Para evitar essa duplicação do mesmo arquivo para tablets e TVs (e a dor de cabeça na manutenção resultante), é possível usar arquivos alias. Por exemplo, os seguintes layouts podem ser definidos:

E adicionar estes dois arquivos:

O conteúdo dos dois últimos arquivos é idêntico, mas eles não definem realmente o layout. Eles apenas configuram main para ser um alias de main_twopanes. Como esses arquivos têm seletores large e sw600dp, eles se aplicam a tablets e TVs independentemente da versão do Android (tablets e TVs anteriores ao 3.2 correspondem a large e posteriores ao 3.2 a sw600dp).

Usar qualificadores de orientação

Alguns layouts funcionam bem em orientações de paisagem e retrato, mas a maioria precisa de ajustes. No aplicativo News Reader de exemplo, o comportamento do layout em cada tamanho e orientação de tela é o seguinte:

Cada um desses layouts é definido em um arquivo XML no diretório res/layout/. Para atribuir cada layout às diversas configurações de tela, o aplicativo usa alias de layout para correspondência em cada configuração:

res/layout/onepane.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

res/layout/onepane_with_bar.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout android:layout_width="match_parent" 
                  android:id="@+id/linearLayout1"  
                  android:gravity="center"
                  android:layout_height="50dp">
        <ImageView android:id="@+id/imageView1" 
                   android:layout_height="wrap_content"
                   android:layout_width="wrap_content"
                   android:src="@drawable/logo"
                   android:paddingRight="30dp"
                   android:layout_gravity="left"
                   android:layout_weight="0" />
        <View android:layout_height="wrap_content" 
              android:id="@+id/view1"
              android:layout_width="wrap_content"
              android:layout_weight="1" />
        <Button android:id="@+id/categorybutton"
                android:background="@drawable/button_bg"
                android:layout_height="match_parent"
                android:layout_weight="0"
                android:layout_width="120dp"
                style="@style/CategoryButtonStyle"/>
    </LinearLayout>

    <fragment android:id="@+id/headlines" 
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="match_parent" />
</LinearLayout>

res/layout/twopanes.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

res/layout/twopanes_narrow.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="200dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

Agora que todos os layouts estão definidos, basta mapear o layout correto a cada configuração usando os qualificadores de configuração. Você pode fazer isso agora usando a técnica de alias de layout:

res/values/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/onepane_with_bar</item>
    <bool name="has_two_panes">false</bool>
</resources>

res/values-sw600dp-land/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-sw600dp-port/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/onepane</item>
    <bool name="has_two_panes">false</bool>
</resources>

res/values-large-land/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes</item>
    <bool name="has_two_panes">true</bool>
</resources>

res/values-large-port/layouts.xml:

<resources>
    <item name="main_layout" type="layout">@layout/twopanes_narrow</item>
    <bool name="has_two_panes">true</bool>
</resources>

Usar bitmaps Nine-patch

Oferecer suporte a diferentes tamanhos de tela normalmente significa que os recursos de imagens devem ter a capacidade de adaptação a diferentes tamanhos. Por exemplo, o fundo de um botão precisa encaixar independentemente do formato aplicado.

Se você usar imagens simples em componentes que podem mudar de tamanho, notará rapidamente que os resultados não são nada impressionantes, pois o tempo de execução esticará ou reduzirá uniformemente as imagens. A solução é usar bitmaps nine-patch, arquivos PNG especialmente formatados que indicam as áreas que não podem ser esticadas.

Portanto, ao projetar bitmaps para uso em componentes com tamanhos variáveis, sempre use nine-patches. Para converter um bitmap em um nine-patch, você pode começar com uma imagem comum (figura 4, mostrada com 4x zoom para clareza).

Figura 4button.png.

Em seguida, execute-o usando o Utilitário draw9patch do SDK (localizado no diretório tools/), onde é possível marcar as áreas que devem ser esticadas desenhando pixels ao longo das bordas esquerda e superior. Você também pode marcar a área para contenção do conteúdo desenhando pixels ao longo das bordas direita e inferior, resultando na figura 5.

Figura 5button.9.png.

Observe os pixels pretos ao longo das bordas. Os pixels nas bordas superior e esquerda indicam os locais em que a imagem pode ser esticada e os nas bordas direita e inferior indicam onde o conteúdo deve ser posicionado.

Observe também a extensão .9.png. Essa extensão precisa ser usada, pois é como a estrutura de trabalho detecta que é uma imagem nine-patch em vez de uma imagem PNG normal.

Quando esse fundo é aplicado a um componente (definindo android:background="@drawable/button"), a estrutura de trabalho estica a imagem corretamente para acomodar o tamanho do botão, como mostrado em diversos tamanhos na figura 6.

Figura 6. Botão usando o button.9.png nine-patch em vários tamanhos.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Siga o Google Developers no WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)