Suporte a múltiplas telas no Android

O Android pode rodar em uma grande variedade de dispositivos que podem ter diferentes tamanhos e densidades de tela. Para as aplicações, o sistema Android fornece um ambiente de desenvolvimento consistente para dispositivos e manipula muita do trabalho para ajustar a interface da aplicação a tela que exibirá a aplicação. Ao mesmo tempo, os sistema fornece APIs que permitem controlar a exibição da aplicação em telas e densidades especificas, para otimizar a interface para diferentes configurções de tela. Por exemplo, você pode querer uma interface para tablets e uma diferente para smartphones.

Apesar do sistema executar o escalamento e redimensionamento para fazer a sua aplicação funcionar em diferentes telas, você deve fazer um esforço para otimizar sua aplicação para diferentes tamanhos e densidades de tela. Fazendo isso, você maximiza a experiência do usuário para todos os dispositivos e os usuários acreditam que sua aplicação foi realmente desenhada para seus dispositivos – ao invés de simplesmente serem esticados para preencher a tela de seus dispositivos.

Seguindo as práticas decritas nesse artigo, você poderá criar uma aplicação que seja exibida adequadamente e fornece uma experiência com o usuário otimizada  em todas as configurações de tela suportadas, usando um único arquivo apk.

Nota: As informações desse documento assume que sua aplicação é desenhada para o Android 1.6 (API Level 4) ou superior.  Se a sua aplicação suporta o Android 1.5 ou inferior, leia Strategies for Android 1.5.

Além disso, esteja ciente de que o Android 3.2 introduziu novas APIs que permitem que você controle precisamente os recursos do leyout que sua aplicação usa para diferentes tamanhos de tela. Esses novos recursos são especialmente importantes se você estiver desenvolvendo uma aplicação otimizada para tablets. Para detalhes, veja a seção Declaring Tablet Layouts for Android 3.2.

Visão geral do suporte a Telas

Essa seção fornece uma visão geral do suporte do Android a múltiplas telas, incluindo: uma introdução aos termos e conceitos usados nesse documento e na API, um sumário das configurações de telas que o sistema suporta, e uma visão geral da API e caracteristicas básicas de compatibilidade de tela.

Termos e conceitos

Screen size
Tamanho atual da tela, medida pela diagonal. Para simplificar, o Android agrupa todos os tamanhos de tela em quatro tamanhos gerais: small, normal, large, and extra large.
Screen density
A quantidade de pixels dentro de uma área física da tela; normalmente é referenciada pela unidade dpi (dots per inch). Por exemplo, uma densidade de tela baixa possui poucos pixels em uma área física, comparada a uma densidade normal ou alta. Para simplificar, o Android agrupa todas as densidades em quatro densidades gerais: low, medium, high, and extra high.
Orientation
A orientação da tela do ponto de vista do usuário. Pode ser retrato ou paisagem, o que significa que o aspecto será vertical ou horizontal. Tenha ciência de que não apenas dispositivos diferentes operam com orientações diferentes, mas a orientação pode mudar durante a execução quando o usuário rotaciona o dispositivo.
Resolution
O número total de pixels físicos da tela. Quando adicionar suporte a múltiplas telas, as aplicações não trabalham diretamente com a resolução; as aplicações devem se preocupar somente com o tamanho e densidade da tela, com especificado nos grupos gerais de tamanho e densidade.
Density-independent pixel (dp)
Uma unidade virtual de pixel que você deveria usar quando definir um layout, para expressar dimensão e posição de forma indenpendente da densidade. O pixel independente da densidade é equivalente a um pixel físico em uma tela de 160 dpi, que é a densidade base assumida pelo sistema para uma tela de densidade “média”. Durante a execução, a tela, de forma transparente, lida com qualquer escalonamento das unidades dp, quando necessário, baseada na densidade atual da tela em uso. A conversão de uma unidade dp para pixel é simples: px = dp * (dpi / 160). Por exemplo, em uma tela de 240 dpi, 1 dp é igual a 1.5 pixels físicos. Você deve sempre usar uma unidade dp quando definir a interface de sua aplicação, para garantir a visualização correta da sua interface em telas de diferentes densidades.

Faixa de telas suportadas

Começando com o Android 1.6 (API Level 4), o Android fornece suporte para múltiplos tamanhos e densidades de tela, que refletem as diversas configurações de tela que os dispositivos podem ter. Você pode usar os recursos do sistema Android para otimizar a interface de sua aplicação para cada configuração de tela e garantir que sua aplicação não apenas seja renderizada corretamente, mas forneça a melhor experiência possivel ao usuário em cada tela.

Para simplificar a maneira de desenhar suas interfaces para múltiplas telas, o Android divide a faixa de tamanhos e densidades de tela em:

  • Um conjunto de quatro tamanhos gerais: small, normal, large, and xlarge. Nota: Começando com o Android 3.2 (API Level 13), esses grupos não são mais usados para dar lugar a uma nova técnica de gerenciar os tamanhos da tela baseado na largura disponivel dela. Se estiver desenvolvendo para o Android 3.2 ou superior, veja Declaring Tablet Layouts for Android 3.2.
  • Um conjunto de densidades gerais: ldpi (baixa), mdpi (média), hdpi (alta), and xhdpi (extra alta)

Os tamanhos e densidades gerais são arranjadas em torno de um configuração base que é tamanho normal e densidade mdpi (média). Essa configuração é baseado na configuração da tela do primeiro dispositivo Android, o T-Mobile G1, que tinha uma tela HVGA (até o Android 1.6, essa era a única configuração de tela suportada pelo Android).

Cada tamanho e densidade geral alcança uma faixa dos tamanhos e densidades existentes. Por exemplo, dois dispositivos que reportem um tamanho de tela normal podem ter de fato tamanhos de tela e aparência um pouco diferentes quando medidos a mão. De forma similar, dois dispositivos que reportem um densidade de tela hdpi poder ter uma densidade de pixel um pouco diferente. O Android torna essas diferenças abstratas para a aplicação, de forma que você pode fornecer uma interface para cada tamanho e densidade e deixar que o sistema manipule qualquer ajuste final necessário. A figura 1 ilustra como os diferentes tmanhos e densidades são categorizados em diferentes grupos:

 

Figure 1. Illustration of how Android roughly maps actual sizes and densities to generalized sizes and densities (figures are not exact).

 

Como você desenha sua interface para diferentes tamanhos de tela, você descobrirá que cada design requer uma quantidade minima de espaço. Assim, cada tamanho de tela geral abaixo tem uma resolução mínima associada que é definida pelo sistema. Esses tamanhos mínimos estão em undades dp – as mesmas unidades que você deve usar quando definir os seus layouts – o que permite que o sistema evite ter que se preocupar com mudanças na densidade da tela.

  • xlarge telas de ao menos 960dp x 720dp
  • large telas de ao menos 640dp x 480dp
  • normal telas de ao menos 470dp x 320dp
  • small telas de ao menos 426dp x 320dp

Nota: Esse tamanhos mínimos de tela  não são bem definidos no Android 3.0, assim você pode encontra alguns dispositivos que podem ser classificados entre normal e large. Esses tamanhos são baseados na resolução física da tela, de forma que pode ser variar entre vários dispositivos – por exemplo um tablet de 1024×720 com uma barra de sistema teria um pouco menos de espaço disponível para a aplicação.

Para otimizar a interface de sua aplicação para diferentes tamanhos e densidades de tela, você pode fornecer recursos alternativos para qualquer um dos tamanhos e densidades gerais. Tipicamente, você deve fornecer layouts alternativos para alguns dos diferentes tamanhos e imagens bitmaps alternativos para densidades diferentes. Durante a execução, o sistema usa os recursos apropriados para sua aplicação, baseada no tamanho e densidade da tela do dispositivo atual.

Você não precisa fornecer recursos alternativos para cada combinação de tela e densidade. O sistema fornece uma recursos de compatibilidade robustos que podem manipular muitos dos trabalhos de renderização em qualquer dispositivo, permitindo que você implemente sua interface usando técnicas que permitem um redimensionamento suave (como descrito na seção Boas práticas, abaixo).

Nota: As características que definem um tamanho e densidade geral são independentes uma da outra. Por exemplo, uma tela WVGA de alta densidade é considerada uma tela de tamanho normal porque seu tamanho físico é quase o mesmo do T-Mobile G1. Por outro lado, uma tela WVGA de densidade média é considerada uma tela de tamanho grande. Apesar de oferecer a mesma resolução (o mesmo número de pixels), A tela WVGA de densidade média tem uma densidade de tela mais baixa, o que significa que cada pixel é fisicamente maior e, assim, a tela é mais larga que a tela de tamanho normal.

Independência de densidade

Sua aplicação alcança “independência de densidade” quando preserva o tamanho físico (do ponto de vista do usuário) dos elementos da interface quando exibidos em telas de densidades diferentes.

Manter independência de densidade é improtante porque, sem ela, um elementos da interface (como um botão) aparecerá fisicamente mais largo em uma tela de baixa densidade e menor numa tela de alta densidade. Cada mudança de tamanho relacionada a densidade pode causar problemas no layout e usabilidade de sua aplicação. As figuras 2 e 3 mostram as diferenças entre uma aplicação quando não fornece independência de densidade e quando fornece, respectivamente.

 

Figure 2. Example application without support for different densities, as shown on low, medium, and high density screens.
Figure 2. Example application without support for different densities, as shown on low, medium, and high density screens.


Figure 3. Example application with good support for different densities (it's density independent), as shown on low, medium, and high density screens.
Figure 3. Example application with good support for different densities (it’s density independent), as shown on low, medium, and high density screens.

 

O sisteam Android ajuda sua aplicação a alcançar indenpendência de densidade de duas formas:

  • O sistema escala as unidades dp de forma apropriada a densidade da tela atual
  • O sistema escala os recursos desenháveis para o tamanho apropriado, baseado na densidade atual da tela, se necessário

Na figura 2, o textview e bitmap tem dimensões especificadas em pixels (unidades px), assim os views são fisicamente maiores numa tela de densidade baixa e maiores numa tela de densidade alta. Isso se deve porque apesar das telas terem tamanhos iguais, telas de densidade alta tem mais pixels por polegada (a mesma quantidade de pixels se encaixam em uma área menor). Na figura 3, as dimensões do layout são especificadas em pixels independentes de densidade (undiades dp). Como a base para os pixels independentes de densidade é uma tela de densidade média, o dispositivo com uma tela de densidade média vai parecer idêntico ao exibido na figura 2. Para telas de densidade baixa e altam  todavia, o sisteam escala os valores dos pixel independentes de densidade para baixo ou para cima, respectivamente, para se encaixar na tela de forma apropriada.

Em muitos casos, você pode gaantir independência de densidade em sua aplicação simplesmente especificando todos os valores das dimensões em pixels independentes de densidade (unidades dp) ou com o “wrap_content”, como for apropriado. O sistema então escala os bitmaps de forma adequada a exibi-los no tamanho correto, baseado no fator de escalonamente adequado para a densidade da tela atual.

Todavia, escalonamento de bitmap pode resultar em bitmaps borrados ou pixelados, o que você pode observar nos screnshots acima. para evitar esses artefatos, você deve fornecer um bitmaps alternativos para densidades diferentes. Por exemplo, você deve fornecer bitmaps de alta resolução para telas de alta resolução e o sistema usará esses ao invés de redimensionar o bitmap feito para uma tela de densidade média. As seções seguintes descrevem mais sobre como suprir os recursos alternativos para diferentes configurações de tela.

Como suportar múltiplas telas

A fundação do suporte do Android para múltiplas telas é a habilidade de gerenciar a renderização do layout e bitmap de uma aplicação de forma adequada para a configuração da tela atual. O sistema manipula muito do trabalho para renderizar sua aplicação de forma apropriada em cada tela escalando os layouts para caber no tamanho e densidade da tela e escalando os bitmpas para a densidade da tela, como for apropriado. Para manipular de forma mais suave as diferentes configurações de tela, porém, você deve também:

  • Explicitamente declarar no manifesto quais tamanhos de tela sua aplicação suporta Pela declaração de quais tamanhos de tela sua aplicação suporta, você pode garantir que apenas dispositivos com as telas que você suporta possam baixar a sua aplicação. Declarando o suporte para telas diferentes pode também afetar como o ssitema desenha a sua aplicação em telas maiores – especificamente, quando a sua aplicação for executada no screen compatibility mode. Para incluir os tamanhos de tela que suan aplicação suporta,  você deve incluir o elemento <supports-screens> no seu arquivo de manifesto.
  • Forneça layouts diferentes para tamanhos de tela diferentes Por padrão, o Android redimensiona o layout de sua aplicação para caber na tela do dispositivo atual. Em muitos casos, isso funciona bem. Em outros casos, sua interface pode não ficar muito bem ajustada e precisam ser feitos ajustes para cada tamanho de tela. Por exemplo, em telas grandes, você pode desejar ajustar a posição e tamanho de alguns elementos para tirar vantagem do espaço adicional na telam ou em telas menores, você pode querer ajustar o tamanho para caber na tela. Os qualificadores disponíveis para fornecer recursos relacionados ao tamanho são small, normal, large, e xlarge. Por exemplo, os layouts para uma tela extra grande devem estar em layout-xlarge/. A partir do Android 3.2, os grupos acima foram descontinuados e você deve usar o qualificador sw<N>dp para definir  a menor largura disponível pelo seu layout. Por exemplo, de o layout do seu tablet requer ao menos 600dp de largura de tela, você deve coloca-lo na pasta layout-sw600dp/. O Uso das novas técnicas de declaração de layout é discutido na seção Declarando layouts para tablets no Android 3.2.
  • Forneça bitmaps diferentes para telas de densidade diferentes Por padrão, o Android escala os bitmaps (arquivos .png, .jpg, and .gif) e desenhos Nine-Patch (arquivos .9.png) de modo que eles sejam renderizados para o tamanho físico adequado para cada dispositivo. Por exemplo, se sua aplicação fornece bitmaps apenas para a densidade média (mdpi), o sistema irá esticar eles quando forem exibidos em uma tela de alta densidade, e encolher quando estiver em uma tela de baixa densidade. Esse escalonamento pode causar defeitos nos bitmaps. Para garantir a melhor aparência dos bitmaps, você deve incluir versões alternativas para cada resolução e densidade de tela. Os qualificadores da configuração que você pode usar são ldpi (low), mdpi (medium), hdpi (high), e xhdpi (extra high). Por exemplo, bitmaps para telas de alta densidade devem estar na pasta drawable-hdpi/.

Os qualificadores para tamanho e densidade correspondem aos tamanhos e densidades gerais descritos na seção acima.

Nota: Se você não estiver familiarizado com os qualificadores e como o sistema usa-os para aplicar os recursos alternativos, leia o  artigo Providing Alternative Resources para obter mais informaçõs.

Durante a execução do aplicativo, o sistema garante a melhor exibição possível na tela atual com os seguintes procedimentos para qualquer recurso fornecido:

  1. O sistema usa recursos alternativos adequados – baseado no tamanho e densidade atual da tela o sistema usa qualquer recurso especifico do tamanho e densidade  fornecido pela sua aplicação. Por exemplo, se o dispositivo possui uma tela de alta densidade e a aplicação requisita um desenho, o sistema verifica por um diretório de recursos que coincida com a configuração do dispositivo. Dependendo das alternativas de recursos disponiveis, um diretório com o qualificador hdpi (como drawable-hdpi/) pode ser a melhor escolha, assim o sistema usa os desenhos desse diretório.
  2. Se nenhum recurso adequado for encontrado, o sistema usa os recursos padrão e estica-os ou comprime-os como for necessário para caber no tamanho da tela – Os recursos padrões são aqueles que não são marcados com um qualificador. Por exemplo, os recursos disponíveis em drawable/são os recursos de desenho padrão. O sistema assume que os recursos padrão são feitos para o tamanho e densidadede tela básica, que é o tamanho normal e densidade média. Assim, o sistema estica os recursos em uma tela de alta densidade e comprime em uma tela de baixa densidade, de forma apropriada. Porém, quando o sistema estiver procurando por um recurso para uma densidade especifica e não encontra o diretório para esse recursos, o sistema nem sempre usa o diretório padrão. Ele pode ao invés disso usar um dos outros diretórios disponíveis para fornecer uma melhor escalonamento. Por exemplo, quando for procurado por um recurso de tela de baixa densidade que não estiver disponível, o sistema prefere comprimir a versão para alta densidade do recurso, já que o sistema escala mais facilmente um recurso de alta densidade para baixa densidade por um fator de 0.5, com poucos defeitos, comparado com o escalonamento  de um recurso de densidade média por um fator de 0.75.

Usando qualificadores para as configurações

O Android suporta vários qualificadores que permitem que você controle como o sistema seleciona os recursos alternativos baseados nas caracteristicas da tela do dispositivo. Um qualificador é uma string que você pode anexar ao diretório do recursos no seu projeto Android e especifica a configuração para o qual os recursos salvos dentro dele foram designados.

Para usar um qualificador:

  1. Crie um novo diretório no diretório res/ do seu projeto e nomeio usando o formato: <resources_name>-<qualifier>
    • <resources_name> é o nome padrão do recursos (como drawable ou layout).
    • <qualifier> é o qualificador da tabela 1, abaixo, especificando a configuração da tela para onde esses recursos foram desenhados (como hdpi ou xlarge).

    Você pode usar mais do que um qualificador ao mesmo tempo – simplesmente separando cada qualificador com um traço.

  2. Salve os recursos especificos da configuração nesse novo diretório. Os arquivos precisam ser nomeados exatamente como os arquivos do recurso padrão.

Por exemplo, xlarge é um qualificador para telas extra grandes. Quando você anexa essa string ao nome do diretório (como layout-xlarge), é indicado ao sistema que esses recursos devem ser usados em dispositivos que possuem um tela extra grande.

Tabela 1.

Screen characteristic Qualifier Description
Size small Resources for small size screens.
normal Resources for normal size screens. (This is the baseline size.)
large Resources for large size screens.
xlarge Resources for extra large size screens.
Density ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
nodpi Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen’s density.
tvdpi Resources for screens somewhere between mdpi and hdpi; approximately 213dpi. This is not considered a “primary” density group. It is mostly intended for televisions and most apps shouldn’t need it—providing mdpi and hdpi resources is sufficient for most apps and the system will scale them as appropriate. If you find it necessary to provide tvdpi resources, you should size them at a factor of 1.33*mdpi. For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi.
Orientation land Resources for screens in the landscape orientation (wide aspect ratio).
port Resources for screens in the portrait orientation (tall aspect ratio).
Aspect ratio long Resources for screens that have a significantly taller or wider aspect ratio (when in portrait or landscape orientation, respectively) than the baseline screen configuration.
notlong Resources for use screens that have an aspect ratio that is similar to the baseline screen configuration.

Por exemplo, a seguir está uma lista de diretórios de recursos em uma aplicação que fornece diferentes layouts para tamanhos de tela difetents e bitmaps diferentes para telas de diversas densidades.

res/layout/my_layout.xml             // layout for normal screen size ("default")
res/layout-small/my_layout.xml       // layout for small screen size
res/layout-large/my_layout.xml       // layout for large screen size
res/layout-xlarge/my_layout.xml      // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation

res/drawable-mdpi/my_icon.png        // bitmap for medium density
res/drawable-hdpi/my_icon.png        // bitmap for high density
res/drawable-xhdpi/my_icon.png       // bitmap for extra high density

Dica: Se você possui algum desenho que o sistema não deve escalonar (talvez por causa de algum ajuste na imagem em tempo de execução), você deve coloca-los em um diretório com o qualificador nodpi. Os recursos com esse qualificador são considerados agnósticos em relação a densidade e o sistema não escala nenhum deles.

Desenhando layouts e figuras alternativas

Os tipos de recursos alternativos que você pode criar depende das necessidades de sua aplicação. Usualmente, você deve usar os qualificadores de tamanho e orientação para fornecer recursos de layout alternativos  e usar os qualificadores de densidade para fornecer bitmaps alternativos para os recursos de desenho.

As seções abaixo resumem as formas que você pode usar os qualificadores de tamanho e densidade para fornecer layouts e desenhos alternativos, respectivamente.

Layouts alternativos

Geralmente, você saberá se precisa de layouts alternativos para telas de tamanho diferente quando testar a sua aplicação em configigurações de tela diferentes. Por exemplo:

  • Quando testando a aplicação em uma tela pequena, você pode descobrir que o seu layout não se encaixa bem na tela. Por exemplo, uma linha de botões pode não caber na largura da tela em uma tela pequena. Nesse caso, você deve fornecer um layout alternativo para telas menores que ajuste o tamanho e posição dos botões.
  • Quando testando a aplicação em uma tela extra grande, você pode perceber que seu layout não torna o uso da tela grande eficiente e é obviamente esticado para preenche-la. Nesse caso, você deve fornecer um layout alternativo para telas extra grandes que fornece uma interface redesenhada que seja otimizada para telas grandes como a tela dos tablets. Apesar de sua aplicação funcionar bem sem um layout alternativo para telas grandes, é muito importante para os usuários que sua aplicação pareça ser desenhada especificamente para os seus dispositivos. Se a interface for obviamente esticada, os usuários ficarão insatisfeitos com a experiência de usar sua aplicação.
  • E, quando testando na orientação paisagem comparada com a orientação retrato, você pode observar que os elementos da interface localizados na parte de baixo da tela na orientação retrato devem estar a direita quando estiver na orientação paisagem.

Para resumir, você deve se certificar que o layout da sua aplicação:

  • Se encaie em telas pequenas (de modo que os usuários possam usar a sua aplicação)
  • Seja otimizada para telas grandes de modo a tirar vantagem do espaço adicional
  • Seja otimizada tanto para orientação paisagem quanto para retrato

Se sua interface usa bitmaps que precisam se encaixar ao tamanho de um view mesmo depois que o sistema escalone o layout (como o plano de fundo de um botão), você deve usar arquivo bitmap Nine-Patch. Esse tipo de arquivo é basicamente um arquivo png no qual você especifica regiões de duas dimensões que são esticáveis. Quando o sistema precisa escalonar o view em que o bitmap é usado, o sistema faz o escalonamento do bitmap Nite-Patch, mas estica apenas as regiões especificadas. Assim, você não precisa fornecer desenhos diferentes para tamanhos de tela diferentes, por que os bitmap Nine_Patch podem ser ajustados a qualquer tamanho. Você deve, porém, fornecer verões alternativas de seus arquivos Nine_Patch para densidades de tela diferentes.

Desenhos alternativos

Figure 4. Relative sizes for bitmap drawables that support each density.
Figure 4. Relative sizes for bitmap drawables that support each density.

Quase toda aplicação deveria ter recursos de desenho alternativos para densidades de tela diferentes, por que quase toda aplicação tem um icone de carregamente e esse icone deve ser apresentado de forma apropriada em todas as densidades de tela. De forma análoga, se você incluir outros bitmaps em sua aplicação (como icones de menu ou outros gráficos), deve fornecer uma versão alternativa para cada densidade.

Nota:  Você precisa apenas fornecer desenhos especificos para a densidade para arquivos bitmap (.png, .jpg, ou .gif) e arquivos Nine-Patch (.9.png). Se você usar arquivos XML para definir shapes, cores ou outros recursos de desenho, dveria colocar uma cópia no diretório padrão (drawable/).

Para criar bitmaps alternativos para densidades diferentes, você deve usar o scaling ratio 3:4:6:8 nas quatro densidades gerais. Por exemplo, se você possuir um bitmap de 48×48 pixels para a tela de densidade média (o tamanho do icone de carregamento), os demais tamanhos devem ser:

  • 36×36 para densidade baixa
  • 72×72 para densidade alta
  • 96×96 para densidade eextra alta

Declarando layout para tablets para o Android 3.2

Na primeira geração de tablets rodando o Android 3.o, a maneira correta de declarar layouts para tablets era coloca-los em um diretório com o qualificador xlarge (por exemplo res/layout-xlarge/). Para que pudessem ser acomodados outros tipos de tablets e tamanhos de tela – em particular, tablets de 7″- o Android 3.2 introduziu uma nova maneira de especificar recursos para tamanhos de tela. A nova técnica é  baseada na quantidade de espaço que seu layout precisa (como 600dp de largura), ao invés de tentar tentar tentar encaixar o layout em grupos genéricos (como large ou xlarge).

A razão que o projeto da interface para tablets de 7″ é complicada ao usar grupos de tamanho gerais é que um tablet de 7″ está tecnicamente no mesmo grupo de smartphone de 5″ (o grupo large). Enquanto esse dois dispositivos são bem  parecidos um do outro em tamanho, a quantidade de espaço para a interface da aplicação é significantemente diferente, em relação a interação com o usuário. Por isso, telas de 7″ e 5″ não devem usar o mesmo layput. Para tornar possivel fornecer diferentes layouts para esses dois tipos de tela, o Android agora permite especificar os recursos de seu layout baseado  na largura e/ou altura que  realmente esteja disponivel para sua aplicação, especificada em unidades dp.

Por exemplo, depois de ter desenhado o layout que você quer para uso em dispositivos tablet, você pode desejar determinar que o layout pare de funcionar bem quando a tela tenha menos de 600dp de largura. Esse limite torna-se o tamanho minimo que você requer para o layout para tablets de sua aplicação. Dessa forma, você pode especificar agora que esses recursos devem ser usados apenas quando existem ao menos 600dp de largura disponível para a interface da aplicação.

Você pode escolher uma largura e determina-la com tamanho minimo, ou testar qual a menor largura que seu layout suporta quando estiver completo.

Nota: Lembre que todas as figuras usadas com essas novas APIs de tamanho estão em valores de pixel independetes de densidade (dp) e as dimensões de seu layout devem sempre estar definidas usando unidades dp, porque o que importa em relação a isso é a quantidade de espaço em tela disponível por causa das contas do sistema para a densidade da tela (ao contrário de usar resolução de pixels brutos).

Usando os novos qualificadores de tamanho

As diferentes configurações de recursos que você pode especificar baseadas no espaço disponível para seu layout são resumidas na tabela 2. Esses novos qualificadores oferecem a você mais controle sobre os tamanhos de tela especificos que sua aplicação suporta, comparados aos tamanhos de tela tradicionais (small, normal, large, e xlarge).

Nota: Os tamanhos que você especifica usando esses qualificadores não são os tamanhos de tela normais. Ao invés disso, os tamanhos são a largura e altura em unidades dp que estão disponíveis para a janela de sua activity. O sistema Android pode usar algumas partes  da tela para a interace do sistema (como a barra de sistema na parte de baixo da tela ou a barra de status na parte de cima), de modo que algumas partes da tela podem não estar disponíveis para o seu layout.  Assim, os tamanhos qu você declara devem ser especificamente sobre os tamanhos que você precisa para sua activity – o sistema leva em conta qualquer espaço usado pela interface do sistema quando declara quanto espaço fornecer para seu layout. Também  leve em conta que a Action Bar é considerada parte da janela de sua aplicação, apesar de seu layout não declara-la, o que reduz o espaço disponivel para o seu layout e você precisa levar isso em conta em seu design.

Tabela 2. Novos qualificadores para tamanhos de tela (introduzidos em Android 3.2)

Configuração da tela Valor do qualificador Descrição
smallestWidth sw<N>dpExamples:
sw600dp
sw720dp
The fundamental size of a screen, as indicated by the shortest dimension of the available screen area. Specifically, the device’s smallestWidth is the shortest of the screen’s available height and width (you may also think of it as the “smallest possible width” for the screen). You can use this qualifier to ensure that, regardless of the screen’s current orientation, your application’s has at least <N>dps of width available for it UI.For example, if your layout requires that its smallest dimension of screen area be at least 600 dp at all times, then you can use this qualifer to create the layout resources, res/layout-sw600dp/. The system will use these resources only when the smallest dimension of available screen is at least 600dp, regardless of whether the 600dp side is the user-perceived height or width. The smallestWidth is a fixed screen size characteristic of the device; the device’s smallestWidth does not change when the screen’s orientation changes.The smallestWidth of a device takes into account screen decorations and system UI. For example, if the device has some persistent UI elements on the screen that account for space along the axis of the smallestWidth, the system declares the smallestWidth to be smaller than the actual screen size, because those are screen pixels not available for your UI.This is an alternative to the generalized screen size qualifiers (small, normal, large, xlarge) that allows you to define a discrete number for the effective size available for your UI. Using smallestWidth to determine the general screen size is useful because width is often the driving factor in designing a layout. A UI will often scroll vertically, but have fairly hard constraints on the minimum space it needs horizontally. The available width is also the key factor in determining whether to use a one-pane layout for handsets or multi-pane layout for tablets. Thus, you likely care most about what the smallest possible width will be on each device.
Available screen width w<N>dpExamples:
w720dp
w1024dp
Specifies a minimum available width in dp units at which the resources should be used—defined by the <N>value. The system’s corresponding value for the width changes when the screen’s orientation switches between landscape and portrait to reflect the current actual width that’s available for your UI.This is often useful to determine whether to use a multi-pane layout, because even on a tablet device, you often won’t want the same multi-pane layout for portrait orientation as you do for landscape. Thus, you can use this to specify the minimum width required for the layout, instead of using both the screen size and orientation qualifiers together.
Available screen height h<N>dpExamples:
h720dp
h1024dp
etc.
Specifies a minimum screen height in dp units at which the resources should be used—defined by the <N>value. The system’s corresponding value for the height changes when the screen’s orientation switches between landscape and portrait to reflect the current actual height that’s available for your UI.Using this to define the height required by your layout is useful in the same way as w<N>dp is for defining the required width, instead of using both the screen size and orientation qualifiers. However, most apps won’t need this qualifier, considering that UIs often scroll vertically and are thus more flexible with how much height is available, whereas the width is more rigid.

Ao mesmo tempo que o uso desses qualificadores parece mais complicado que usar os grupos de tamanho, deve ficar mais simples quando você determinar os requerimentos de sua interface. Quando você projeta sua interface, sua preocupação principal deve ser o tamanho em que sua aplicação irá mudar entre uma interface para smartphones e uma interface para tablets que usa paineis múltiplos. O ponto exato dessa mudança dependerá  do seu design em particular – pode ser que você precise de 720dp para o layout de seu tablet, pode ser que 600dp seja suficiente, ou 480dp, ou algum número entre esses. Usando esses qualificadores da tabela 2, você estará no controle do tamanho preciso da largura onde seu layout muda.

Exemplos de configurações

Para ajudar você a definir o alvo de seu design para tipos de diferentes de dispositivos, aqui estão alguns números para larguras de tela típicas:

  • 320dp: uma tela de smartphone típica (240×320 ldpi, 320×480 mdpi, 480×800 hdpi, etc).
  • 480dp: um tablet pequeno como o Streak (480×800 mdpi).
  • 600dp: um tablet de 7” (600×1024 mdpi).
  • 720dp: um tablet de 10” (720×1280 mdpi, 800×1280 mdpi, etc).

Usando os qualificadores da tabela 2, sua aplicação pode mudar entre os diferentes recursos do layout para smartphones e tablets usando qualquer número de sua escolha para a largura e/ou altura. Por exemplo,  se 600do for a menor largura disponível para o seu layout para tablets, você pode fornecer esses dois conjuntos de layouts:

res/layout/main_activity.xml           # For handsets
res/layout-sw600dp/main_activity.xml   # For tablets

Nesse caso, a menor largura da tela disponível precisa ser 600dp para que o layout para tablets seja aplicado.

Para os outros casos onde você quiser personalizar sua interface para se diferenciar entre os tamanhos, como os tablets de 7″ e 10″, você pode definir layouts adicionais:

res/layout/main_activity.xml           # For handsets (smaller than 600dp available width)
res/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide and bigger)
res/layout-sw720dp/main_activity.xml   # For 10” tablets (720dp wide and bigger)

Observe que os dois conjuntos anteriores de recursos exemplos usam o qualificador “smallest width”, sw<N>dp, que especifica a menor tela, sem levar em consideração a orientação do tablet. Assim, usando sw<N>dp é a maneira mais simples para especificar todos os tamanhos de tela disponíveis para o seu layout ignorando a orientação da tela.

Todavia, em muitos casos, o que pode ser importante para o seu layout é exatamente quanta largura ou altura está disponível. Por exemplo, se você tem um layout de dois paineis com dois fragmentos lado a lado, pode querer usar-los não importando se a tela fornece ao menos 600dp de largura, estando o dispositivo na orientação paisagem ou retrato. Nesse caso, seus recursos devem parecer com isso:

res/layout/main_activity.xml         # For handsets (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # Multi-pane (any screen with 600dp available width or more)

Observe que o segundo conjunto está usando o qualificador “available width”, w<N>dp. Dessa maneira, o dispositivo pode usar ambos os layouts, dependendo da orientação da tela (se estiver disponível ao menos 600dp em uma orientação e menos de 600dp em outra).

Se a altura disponível for uma preocupação para você, então você pode fazer o mesmo usando o qualificador h<N>dp. Ou, mesmo combinar os qualificadores w<N>dp e h<N>dp se você precisa ser realmente especifico.

Declarando o suporte ao tamanho da tela

Uma vez que você tiver implementado seus layouts para os diferentes tamanhos de tela, é igualmente importante que você declare em seu arquivo de manifesto quais telas sua aplicação suporta.

Junto com os novos qualificadores para o tamanho da tela, o Android 3.2 introduz novos atributos para o elemento do manifesto <supports-screens>:

android:requiresSmallestWidthDp
Especifica o mínimo smallestWidth necessário. Esse valor é a menor dimensão de espaço em tela (em unidades dp) que precisam estar disponíveis para sua aplicação – isto é, a menor das duas dimensões de tela disponíveis. Assim, para que o disposítivo seja compatível com sua aplicação, o valor de smallestWidth de seu dispositivo precisa ser igual ou maior que esse valor. (Usualmente, o valor que você suprir para esse atributo é o “smallest width” que o seu layout suporta, não importando a orientação da tela). Por exemplo, se sua aplicação for desenhada apenas para tablets com uma largura mínima de 600dp:
<manifest ... >
    <supports-screens android:requiresSmallestWidthDp="600" />
    ...
</manifest>

Porém, se a sua aplicação suporta todos os tamanhos de tela suprotados pelo Android (tão pequenos quanto 460dp x 320dp), então você não precsisa declarar esse atributo, porque a menor largura que a suan aplicação requer é a menor possível em qualquer dispositivo.

Cuidade: O sistema Android não dá atenção a esse atributo, de modo que não afeta o comportamento de sua aplicação durante a execução. Ao invés disso, esse atributo é usado apra ativar a filtragem de sua aplicação em serviços como o Android Market. Porém, o Android Market ainda não suporta esse atributo para flitragem (no Android 3.2), assim você deve continuar usando os outros atributos de tamanho que sua aplicação não suporta telas pequenas.

android:compatibleWidthLimitDp
Esse atributo permite que você ative o screen compatibility mode como um recusos opcional para o usuário pela especificação do máximo “smallest width” que a sua aplicação suporta. Se o menor lado dea tela de um dispositivo for maior que o valor desse atributo, os usuário poden ainda instalar sua aplicação, mas irão roda-la no modo de compatibilidade. Por padrão, esse modo é desativado e seu layout é redimensionado para caber na tela, mas um botão estará disponível na barra de sistema que permitirá que o usuário alterne entre ligar ou desligar esse modo de compatibilidade. Nota: Se o layout de sua aplicação puder ser redimensionado de forma correta em telas grandes, você não precisa usar esse atributo. É recomendado evitar usar esse atributo e ao invés disso garantir o redimensionamento correto em telas grandes seguindo as recomendações desse artigo.
android:largestWidthLimitDp
Esse atributo permite que você force o ativamento do screen compatibility mode pela especificaçãoi do valor máximo de “smallest width” que a sua aplicação suporta. Se o menor lado da tela disponível do dispositivo for maior que o valor desse atributo, a aplicação será executada em modo de compatibilidade sem nenhuma forma do usuário destiva-lo. Nota: Se o layout de sua aplicação puder ser redimensionada corretamento para telas grandes, você não precisa dessa atributo. É recomendado evitar usar esse atributo e ao invés disso grantor que o seu layout possa ser redimensionado para telas grandes seguindo as recomendações desse artigo.

Cuidado: Quando você estiver desenvolvendo para o Android 3.2 ou superior, você não deve usar os atributos de tamanho de tela antigos em combinação com os atributos listados acima. Usando os novos atributos junto com os antigos, comportamentos inexperados podem acontecer.

Boas práticas

O objetivo de suportar múltiplas telas é criar uma aplicação quem possa funcionar de forma adequada e ter uma boa aparência em qualquer configurações de tela genéricas suportadas pelo Android. As seções anteriores desse artigo fornecem informações sobre como o Android adapta sua aplicação  para as configurações de tela e como você pode personalizar a aparência de sua aplicação nesse configurações diferente. Essa seção fornece algumas dicas adicionais e uma visão geral das técnicas que ajudam a garantir que a sua aplicação possa ser escalonada apropriadamente para configurações de tela diferentes.

1. Use wrap_content, fill_parent, ou a unidade dp para as dimensões do layout

Quando definir android:layout_width e android:layout_height para as views no arquivo XML do layout, use "wrap_content", "fill_parent" ou unidades dp para garantir que a view receba um tamanho apropriado na tela do dispositivo atual.

Por exemplo, uma view com o atributo layout_width="100dp" mede 100 pixels de largura em uma tela de densidade média e o sistema estica ele para 150 pixels em uma tela de alta densidade, para que ocupe aproximadamente o mesmo espaço na tela.

De forma similar, você deve dar preferência a sp (scale-independent pixel) para definir os tamanhos do texto. O fator de escalonamento do sp depende configuração do usuário e o sistema redimensiona o tamanho de forma igual com faz para o dp.

2. Não use valores fixos de pixel no código de sua aplicação.

Por questão de performance e manter o código simples, o sistema Android usa pixels como a unidade padrão para expressar dimensões os valores de coordenadas. Isso significa que as dimensões de um view são sempre expressos no código usando pixels, mas sempre baseados na densidade da tela atual. Por exemplo, se myView.getWidth() retorna 10, o view tem 10 pixels de largura na tela atual, mas em um dispositivo com uma tela de maior densidade, o valor de retorno pode ser 15. Se você usar os valores de pixel no código de sua aplicação para trabalhar com bitmapsm que não são pré-escalados para a densidade da tela atual, pode precisar escalar os valores dos pixel que você usar em seu código para bater com os bitmaps originais.

3. Não use o AbsoluteLayout

Ao contrário de outros widgets relacionados a layout, AbsoluteLayout força o uso de posições fixas para mostrar as views filhas, o que pode facilmente levar a interfaces que não funcionam bem em telas diferentes. Por causa disso, o AbsoluteLayout foi descontinuado no Android 1.5 (API Level 3).

Você deve usar ao invés dele o RelativeLayout, que usa posicionamento relativo para mostrar os views. Por exemplo, você pode especificar que um botão deve aparecer “a direita de” um widget de texto.

4. Use os recursos especificos de tamanho e densidade

Apesar do sistema escalonar seu layout e recursos de desenho baseando-se nas configuração da tela atual, você pode querer ajustar a interface para tamanhos de telas diferentes e fornecer bitmaps que sejam otimizados para diferentes densidades. Isso essencialmente reitera a informação desse artigo.

Se você precisa controlar exatamente a aparência de sua aplicação em várias configurações de tela, ajuste seus layouts e bitmaps nos diretórios dos recursos. Por exemplo, considere um ícone que você queira exibir em telas de densidade média e alta. Simplesmente crie seu ícone em dois tamanhos diferentes (por exemplo, 100×100 para densidade média e 150×150 para densidade alta) e coloque as duas variações nos diretório apropriados, usando os qualificadores apropriados:

res/drawable-mdpi/icon.png   //for medium-density screens
res/drawable-hdpi/icon.png   //for high-density screens

Nota: Se o qualificador de densidade não está definido no nome do diretório, o sistema assume que os recursos desse diretório são desenhados para a densidade média e redimensionará os recursos para as outras densidades.

Considerações adicionais sobre a densidade

Essa seção descreve mais sobre como o Android executa o escalonamento de bitmaps em telas de densidades diferentes e como você pode controlar como esses bitmaps são desenhados nessas telas diferentes. A informação dessa seção pode não ser importante para muitas aplicações, a menos que você encontre problemas quando executar sua aplicação em telas de densidades diferentes ou se sua aplicação manipula gráficos.

Para entender melhor como você pode suportar múltiplas densidades quando estiver manipulando gráficos em tempo de execução, você deve entender que o sistema ajuda a garantir a escala adequada para os bitmaps em uma das formas abaixo:

  1. Pré-escalonamento dos recursos (como bitmaps) Baseando-se na densidade da tela atual, o sistema usa qualquer recurso especifico para o tamanho ou densidade de sua aplicação e exibe-os sem escalonamento. Se o recurso não estiver disponível na densidade correta, o sistema carrega os recursos padrão e redimensiona eles da forma necessária para caber na tela atual. O sistema assume que os recursos padrão (os que estão num diretório sem qualificadores) são desenhados para uma tela de densidade média (mdpi), a menos que sejam carregadas de um diretório de recurso específico. O pré-escalonamento é, assim, o que o sistema faz quando redimensiona um bitmap para o tamanho apropriado para a tela em uma densidade especifica. Se você requisitar as dimensões de uma recursos pré-escalonado, o sistema retorna o valores que representam as dimensões pós-escalonamento. Por exemplo, um bitmap desenhado em 50×50 para uma tela mdpi é redimensionado para 75×75 em uma tela hdpi (se não houver um recursos alternativo paa hdpi) e o sistema reporta o tamanho dessa forma. Existem algumas situações em que você pode querer que o Android não pré-escale um recursos. A maneira mais fácil de evitar isso é colocar o recursos em um diretório com o qualificador nodpi. Por exemplo:
    res/drawable-nodpi/icon.png

    Quando o sistema usar o bitmap icon.png dessa pasta, ele não redimensionará ele com base na densidade do dispositivo.

  2. Auto-escalonamento das dimensões e coordenadas do pixel Uma aplicação pode desativar o pré-escalonamento pela configuração do atributo android:anyDensity para “false” no manifesto ou através do código-fonte para um Bitmap pela configuração do atributo inScaled para "false". Nesse caso, o sistema auto-escala qualquer coordenada absoluta e dimensão de pixels durante o desenho do recursos. Isso garante que os elementos da tela  serão ainda exibidos n omesmo tamanho físico aproximado como se eles fossem exibidos em uma tela de densidade média (mdpi). O sistema manipula esse escalonamento de forma transparente para a aplicação e reporta as dimensões escalonadas do pixel para a ela, ao invés dos valores físicos do pixel. Por exemplo, suponha que um dispositivo tenha uma tela WVGA de alta densidade, que tem 480×800 e quase o mesmo tamanho  da tela HVGA, mas esteja executando uma aplicação que desativou o pré-escalonamento. Nesse caso, o sistema enganará a aplicação quando ela consultar as dimensões da tela, e reportará 320×533 (a tradução aproximada da tela mdpi para a densidade da tela). Assim, quando a aplicação  executar alguma operação de desenho, como a invalidação de uma retângulo de (10,10) para (100,100), o sistema transforma as coordenadas pelo escalonamento delas, e na verdade redimensiona a região (15,15) para (150,150). Essa discrepância pode causar comportamentos inexperados se a sua aplicação manipula diretamente os bitmaps, mas isso é considerado uma situação aceitável por manter a performance da aplicação num nível bom. Se você de encontrar nessa situação, leia  seção a seguir. Usualmente, você não deve desativar o pré-escalonamento. A melhor forma de suportar múltiplas telas é seguir as técnicas descritas acima na seção Como suportar múltiplas telas.

Se a sua aplicação manipula bitmaps ou interage diretamente com os pixels da tela de alguma forma, você pode precisar seguir alguns passos adicionais para suportar densidades de tela diferentes. Por exemplo, se você responde a gestos de toque pela contagem do número de pixel que um dedo cruza, precisa usar os valores apropriados dos pixels independentes da densidade, ao invés dos pixel normais.

Escalando bitmaps criados durante a execução

Figure 5. Comparison of pre-scaled and auto-scaled bitmaps, from ApiDemos.
Figure 5. Comparison of pre-scaled and auto-scaled bitmaps, from ApiDemos.


Se a sua aplicação cria um bitmap na memória (um objeto Bitmap), o sistema assume que o bitmape é desenhado para uma tela de densidade média, por padrão, e auto-escala o bitmap durante o desenho. O sistema aplica o “auto-escalamento” para um Bitmap quando ele não especifica as propriedades de densidade. Se você não calcular corretamente a densidade da tela do dispositivo atual e especificar as propriedades de densidade do bitmap, a auto-escala pode resultar em defeitos da mesma forma quando você fornece recursos alternativos.

Para controlar se um Bitmap criado durante a execução será escalado ou não, você pode especificar a densidade dele com o método setDensity(), passando uma constante de densidade de DisplayMetrics, como DENSITY_HIGH ou DENSITY_LOW.

Se você criar um Bitmap usando  o BitmapFactory, como a partir de um arquivo ou stream, você pode usar BitmapFactory.Options para definir as propriedades do bitmap que já existe, o que determina como o sistema irá escalonar ele. Por exemplo, você pode usar o campo inDensity para definir a densidade para a qual o bitmap é desenhado e o campo inScaled especifica se o bitmap deve ser escalado para caber na tela do dispositivo.

Se você configurar o campo inScaled para false, então você desativa o pré-escalonamento que o sistema poderia aplicar ao bitmap e o sistema irá então auto-escalonar ele durante a execução. Usar o auto-escalonamento ao invés do pré-escalonamento usa mais CPU, mas menos memória.

A figura 5 demonstra os resultados dos mecanismos de pré-escalonamento e auto-escalonamento quando carregando bitmaps de densidade baixa (120), média (160) e alta (240) em uma tela de alta densidade. As diferenças são sutis, porque todos os bitmaps são escalonamdos de acordo com a densidade da tela atual, porém os bitmaps escalonados tem pequena diferenças dependendo de serem pré-escalonados ou auto-escalonados.

Convertendo unidades dp em pixels

Em alguns casos, você precisa expressar dimensões em unidades dp e depois converte-las para pixels. Imagine uma aplicação em um gesto e rolagem ou lançamento seja reconhecido depois que o dedo do usuário se mova por pelo menos 16 pixels. Numa tela base, um usuário precisa mover-se por 16 pixels / 160 dpi, o que equivale a 1/10 de uma polegada (ou 2.5 mm) antes que o gesto seja reconhecido. Em um dispositivo com um display de alta densidade (240 dpi), o usuário precisa mover-se por 16 pixels / 240 dpi, o que equivale a 1/15 de uma polegada (1.7 mm). A distância é muito mais curta e a aplicação dessa forma aparenta ser mais sensivel ao usuário.

Para corrigir esse problema, limiar do gesto precisa ser expresso no código em dp e depois convertido para pixel. Por exemplo:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

O campo DisplayMetrics.density especifica o fator de escalonamento que você precisa usar para converter unidades dp para pixels, de acordod com a densidade da tela. Em uma tela de densidade média, o DisplayMetrics.density é igual a 1.0; em uma tela de alta densidade é igual a 1.5; em uma tela de densidade extra grande, é igual a 2.0; e em  uma tela de densidade baixa, é igual a 0.75. Isso mostra o fator pelo qual você deve multiplicar a unidade dp para obter a quantidade de pixels para a tela (em seguida adicione 0.5f para arredondar a figura para o número inteiro mais próximo, quando converter para um inteiro).

Porém, ao invés de  definir um limite arbitrário para esse tipo de evento, você pode usar valores de configuração pré-escalonados que estão disponíveis em ViewConfiguration.

Usando valores de configuração pré-escalados

Você pode usar a classe ViewConfiguration para acessar distância comuns, velocidades e tempos usados pelo sistema Android. Por exemplo, a distância em pixels usados pelo framework como limite de rolagem pode ser obtida com getScaledTouchSlop():

private static final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();

Os métodos de ViewConfiguration que começam com o prefixo getScaled garantem um valor de retorno em pixels que poderá ser exibido não importando a densidade dad tela.

Como testar a sua aplicação em múltiplas telas

Figure 6. A set of AVDs for testing screens support.
Figure 6. A set of AVDs for testing screens support.


Antes de publicar a sua aplicação, você deve testa-la em todas os tamanhos e densidades de tela suportados. O SDK do Android inclui um emulador que você pode usar, que replica os tamanhos e densidades de configurações comuns onde sua aplicação pode ser executada. Você pode também modificar o tamanho, densidade e resolução padrão do emulador para replicar as características de uma tela especifica. Usando o emulador e configurações personalizadas adicionais permitem a você testar qualquer configuração possível, de forma que você não precisa comprar vários dispositivos para testar o suporte a telas de sua aplicação.

Para configurar um ambiente para teste do suporte a telas de sua aplicação, você deve criar uma série de AVDs (Android Virtual Devices), usando o emulador e as configurações de tela que emulam os tamanhos e densidades da tela que você quer que sua aplicação suporte. Para fazer isso, você pode usar o SDk do Android e o AVD Manager para criar as AVDs e carrega-las com uma interface gráfica.

Para carregar o Android SDk e o AVD Manager, execute SDK Manager.exe do diretório do SDK do Android (no Windows) ou execute android do diretório <sdk>/tools/ (nas outras plataformas). A figura 6 mostra os SDk do Android e o AVD Manager com uma seleção de AVDs, para teste de várias configurações de tela.

A tabela 3 mostra os vários emuladores que estão disponíveis no SDK do Android, que você pode usar para emular algumas das configurações de tela comuns.

Tabela 3.

Low density (120), ldpi Medium density (160), mdpi High density (240), hdpi Extra high density (320), xhdpi
Small screen QVGA (240×320) 480×640
Normal screen WQVGA400 (240×400)
WQVGA432 (240×432)
HVGA (320×480) WVGA800 (480×800)
WVGA854 (480×854)
600×1024
640×960
Large screen WVGA800** (480×800)
WVGA854** (480×854)
WVGA800* (480×800)
WVGA854* (480×854)
600×1024
Extra Large screen 1024×600 WXGA (1280×800)
1024×768
1280×768
1536×1152
1920×1152
1920×1200
2048×1536
2560×1536
2560×1600
* To emulate this configuration, specify a custom density of 160 when creating an AVD that uses a WVGA800 or WVGA854 skin.
** To emulate this configuration, specify a custom density of 120 when creating an AVD that uses a WVGA800 or WVGA854 skin.
† This skin is available with the Android 3.0 platform

 

Figure 7. Size and density options you can set, when starting an AVD from the Android SDK and AVD Manager.
Figure 7. Size and density options you can set, when starting an AVD from the Android SDK and AVD Manager.


Também é recomendado testar sua aplicação em um emulador que esteja configurado para rodar com uma tamanho físico que seja próximo a um dispositivo real. Isso torna fácil comparar os resultados entre vários tamanhos e densidades. Para fazer isso, você precisa saber a densidade aproximada, em dpi, do monitor de seu computador (por exemplo, um monitor Dell de 30 tem uma densidade de aproximadamente 96 dpi). Quando você carregar uma AVD, pode especificar o tamanho da tela para o emulador e o dpi de seu monitor em Launch Options, como mostrado na figura 7.

Se você quiser testar a sua aplicação em uma tela que use um resolução ou densidade não suportada pelos AVDs internos, pode criar um AVD que use uma resolução ou densidade personalizada. Quando criar a AVD a partir do SDK do Android e AVD Manager, especifique a Resolução ao invés de selecionar a AVD.

Se quiser carregar sua AVD pela linha de comando, pode especificar a escala para o emulador com a opção -scale. Por exemplo>

emulator -avd <avd_name> -scale 96dpi

Traduzido de http://developer.android.com/guide/practices/screens_support.html

  • Paulo Linhares

    Nossa, muito bom ! Completa explicação. Mas ainda estou passando por um problema numa aplicação minha aqui relacionado a este assunto. Veja se pode me ajudar:
    No meu caso tenho um ImageView que mostra uma régua, e então eu precisaria mostrar essa régua no tamanho real , onde ela não precisa crescer ou diminuir conforme o tamanho da tela ou densidade. Usando como base meu Moto G3, ela funciona perfeitamente, mas quando testo em outros devices, ela perde o tamanho real de uma régua porque a imagem tenta se adequar ao tamanho da tela. A imagem da régua está em PNG e mede 3600px x 155px e possui medida até os 30cm, está dentro de um LinearLayout Orizontal. Em meu Moto G3 a área visível dela fica em 10cm, numa tela maior por exemplo ela deveria mostrar uma área maior da régua (11 a 15cm por exemplo), mas ela contunua apenas em 10cm no campo visual da tela, mostrando que ela cresce e encolhe conforme as configurações de tela e densidade do device. Antes eu tinha uma imagem da rágua para cada recurso(xxhdpi, xhdpi, etc), daí resolvi migrar ela para a pasta assets do Android, mas continuo com o mesmo problema. Você tem uma luz de como corrigir isso?

    • Olá Paulo. Já faz algum tempo que tive que lidar com isso; então a única sugestão que você eu poderia te passar seria tentar revisar alguma configuração do ImageView onde a imagem está. Dê uma olhada na documentação dessa classe pra ver se existe alguma propriedade que quando ajustada possa tornar o tamanho da imagem fixa.

      • Paulo Linhares

        Tudo bem Kleber. Vou pesquisar sobre ! Obrigado pelo retorno.

  • Armando Marques Sobrinho

    cara!

    me ajudou pra caramba com isso
    voce pode ver o resultado em:
    https://play.google.com/store/apps/details?id=com.armando.fases_da_lua

    Eu estava tendo problemas com as telas dos dispositivos, deu um trabalhão para adequar as variaveis para cada resolução mas era isso mesmo que eu queria

    valeu pelo post!

  • sanchessd

    Obrigado pela atenção, vou criar um projeto novo especificamente pra isso, vou ver se consigo resolver o caso com as sugestões.

  • Olá, primeiramente obrigado por ler e comentar nesse blog. Em relação a sua duvida, de acordo com meus cálculos com base no scaling ratio 3:4:6:8, as tamanhos deveriam ser: 240×360, 320×480, 480×720 e 640×960. Caso o dispositivo alvo tenha uma resolução diferente, o Android deveria redimensionar a imagem para o tamanho da tela. Caso não queira isso, acredito que exista como criar um conjunto de imagens para uma resolução personalizada. Vou dar uma olhada nisso e tento responder aqui o mais rápido possível.

  • sanchessd

    Olá, primeiramente quero parabenizar pelo post, pois é o mais completo que achei..

    Eu desenvolvo aplicativos para IOS a algum tempo, e a pouco comecei desenvolver para android, e o que mais me encomoda é ajustar a tela para varios dispositivos devido ao fato que no IOS é bem simples e tenho os aparelhos para testes, mas no android não tenho todos equipamentos para saber se realmente ficou certinho…

    O que ainda não consegui me adaptar é fazer com que imagens sejam exibidas na mesma proporção sem distorcer ou dimininuir e ferrar com o layout.

    neste treixo:
    Para criar bitmaps alternativos para densidades diferentes, você deve usar o scaling ratio 3:4:6:8 nas quatro densidades gerais. Por exemplo, se você possuir um bitmap de 48×48 pixels para a tela de densidade média (o tamanho do icone de carregamento), os demais tamanhos devem ser:

    36×36 para densidade baixa
    72×72 para densidade alta
    96×96 para densidade eextra alta

    Para este exemplo entendi, mas se eu tiver uma imagem de fundo que pega toda a tela por exemplo, o tamanho normal é 320×480 que seria para smartphones, mas tenho smartphones considerados como "normais" com a resolução de 480×800 e depois vem o tablets etc..

    Qual o calculo que tenho que fazer para que o tamanhos fiquem certos e não "sobre" cantos brancos na aplicação ? e tem algum atributo de gravity que devo usar no ImageView ?

    Minha dificuldade se resume a esses pontos, nunca consigo que um botao seja exibido no mesmo lugar e no mesmo tamanho sem distorcer em diferentes telas.

    Peço desculpas pelo tamanho do comentario (dúvida), mas realmente isso me encomoda e preciso aprender de uma forma ou outra.

    Obrigado!

    • Uma sugestão que você pode tentar é criar, dentro da pasta res/ de seu projeto, uma pasta com o nome layout-sw800dp, e salvar dentro dela os arquivos específicos para esse tamanho de tela.

  • Pingback: Estrutura básica de um projeto Android | Guia do Desenvolvedor()