As classes de tamanho de janela são um conjunto de pontos de interrupção específicos da janela de visualização que ajudam você projetar, desenvolver e testar layouts responsivos/adaptáveis. Os pontos de interrupção equilibram a simplicidade do layout com a flexibilidade de otimizar o app para casos únicos.
As classes de tamanho de janela categorizam a área de exibição disponível para o app como compacta, média ou expandida. A largura e a altura disponíveis são classificadas separadamente, para que, a qualquer momento, o app tenha dois tamanhos de janela classes, uma para largura e outra para altura. A largura disponível geralmente é maior importante que a altura disponível devido à onipresença da rolagem vertical, então a classe de tamanho de janela para a largura provavelmente é mais relevante para a interface do usuário do seu app.
Conforme visualizado nas figuras, os pontos de interrupção permitem que você continue pensando sobre layouts em termos de dispositivos e configurações. Cada ponto de interrupção de classe de tamanho representa um caso majoritário para cenários de dispositivos típicos, que podem ser uma referência útil enquanto você pensa sobre o design dos seus layouts baseados em pontos de interrupção.
Classe de tamanho | Ponto de interrupção | Representação do dispositivo |
---|---|---|
Largura compacta | largura < 600 dp | 99,96% dos smartphones no modo retrato |
Largura média | 600 dp ≤ largura < 840 dp | 93,73% dos tablets no modo retrato
a maioria das telas internas desdobradas no modo retrato |
Largura expandida | largura ≥ 840 dp | 97,22% dos tablets no modo paisagem
a maioria das telas internas desdobradas no modo paisagem |
Altura compacta | altura < 480 dp | 99,78% dos smartphones no modo paisagem |
Altura média | 480 dp ≤ altura < 900 dp | 96,56% dos tablets no modo paisagem
97,59% de smartphones no modo retrato |
Altura expandida | altura ≥ 900 dp | 94,25% de tablets no modo retrato |
Embora visualizar classes de tamanho como dispositivos físicos possa ser útil, o tamanho da janela não são determinadas explicitamente pelo tamanho da tela do dispositivo. Janela As classes de tamanho não se destinam à lógica do tipo isTablet. Em vez disso, a janela As classes de tamanho são determinadas pelo tamanho da janela disponível para o aplicativo independentemente do tipo de dispositivo em que o app está sendo executado, que tem duas funções implicações:
Os dispositivos físicos não garantem uma classe de tamanho de janela específica. O o espaço na tela disponível para o app pode ser diferente do tamanho da tela do dispositivo por diversos motivos. Em dispositivos móveis, o modo de tela dividida pode particionar a tela entre dois aplicativos. No ChromeOS, os apps Android podem: ser apresentados em janelas de formato livre e redimensionáveis arbitrariamente. Os dobráveis podem ter duas telas de tamanhos diferentes acessadas individualmente dobrando ou desdobrando o dispositivo.
A classe de tamanho de janela pode mudar durante o ciclo de vida do app. Enquanto o app está em execução, a orientação do dispositivo muda, é multitarefa e dobrar/desdobrar pode alterar a quantidade de espaço disponível na tela. Como a classe de tamanho de janela é dinâmica e a interface do app precisa se adaptar de acordo.
As classes de tamanho de janela mapeiam para os pontos de interrupção compactos, médios e expandidos na Layout do Material Design e orientações on-line. Use classes de tamanho de janela para tomar decisões de layout de aplicativo de alto nível, como decidir usar um layout canônico específico para aproveitar mais espaço na tela.
É possível calcular o valor
WindowSizeClass
usando o
WindowSizeClass#compute()
fornecida pelo comando Jetpack
WindowManager. O exemplo a seguir
mostra como calcular a classe de tamanho de janela e receber atualizações sempre que o
mudanças de classe de tamanho de janela:
Kotlin
class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // Replace with a known container that you can safely add a // view to where the view won't affect the layout and the view // won't be replaced. val container: ViewGroup = binding.container // Add a utility view to the container to hook into // View.onConfigurationChanged(). This is required for all // activities, even those that don't handle configuration // changes. You can't use Activity.onConfigurationChanged(), // since there are situations where that won't be called when // the configuration changes. View.onConfigurationChanged() is // called in those scenarios. container.addView(object : View(this) { override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) computeWindowSizeClasses() } }) computeWindowSizeClasses() } private fun computeWindowSizeClasses() { val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this) val width = metrics.bounds.width() val height = metrics.bounds.height() val density = resources.displayMetrics.density val windowSizeClass = WindowSizeClass.compute(width/density, height/density) // COMPACT, MEDIUM, or EXPANDED val widthWindowSizeClass = windowSizeClass.windowWidthSizeClass // COMPACT, MEDIUM, or EXPANDED val heightWindowSizeClass = windowSizeClass.windowHeightSizeClass // Use widthWindowSizeClass and heightWindowSizeClass. } }
Java
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... // Replace with a known container that you can safely add a // view to where the view won't affect the layout and the view // won't be replaced. ViewGroup container = binding.container; // Add a utility view to the container to hook into // View.onConfigurationChanged(). This is required for all // activities, even those that don't handle configuration // changes. You can't use Activity.onConfigurationChanged(), // since there are situations where that won't be called when // the configuration changes. View.onConfigurationChanged() is // called in those scenarios. container.addView(new View(this) { @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); computeWindowSizeClasses(); } }); computeWindowSizeClasses(); } private void computeWindowSizeClasses() { WindowMetrics metrics = WindowMetricsCalculator.getOrCreate() .computeCurrentWindowMetrics(this); int width = metrics.getBounds().width int height = metrics.getBounds().height() float density = getResources().getDisplayMetrics().density; WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density) // COMPACT, MEDIUM, or EXPANDED WindowWidthSizeClass widthWindowSizeClass = windowSizeClass.getWindowWidthSizeClass() // COMPACT, MEDIUM, or EXPANDED WindowHeightSizeClass heightWindowSizeClass = windowSizeClass.getWindowHeightSizeClass() // Use widthWindowSizeClass and heightWindowSizeClass. } }
Testar classes de tamanho de janela
À medida que você faz mudanças no layout, teste o comportamento dele em todos os tamanhos de janela, especialmente nas larguras compactas, médias e expandidas dos pontos de interrupção.
Se você já tem um layout para telas compactas, primeiro otimize-o para a classe de tamanho de largura expandida, já que essa classe de tamanho fornece mais espaço para ver mais conteúdo e alterações na interface. Em seguida, decida qual layout faz sentido para a classe de tamanho com largura média, considere adicionar um layout especializado.
Próximas etapas
Para saber mais sobre como usar classes de tamanho de janela para criar modelos responsivos/adaptáveis. layouts, consulte o seguinte:
Para layouts baseados no Compose: Suporte para tamanhos de tela diferentes
Para layouts baseados em visualização: Design responsivo/adaptável com visualizações
Para saber mais sobre o que faz um app funcionar bem em todos os dispositivos e tamanhos de tela, consulte: