Telas grandes desdobradas e estados dobrados exclusivos permitem novas experiências do usuário em dispositivos dobráveis. Para que o app reconheça um dispositivo dobrável no Jetpack Compose, use a biblioteca Adaptive do Compose Material 3, que fornece APIs para recursos de janela de dispositivos dobráveis, como dobras, articulações e posições do dispositivo. Quando o app reconhece dobras, ele pode adaptar o layout para evitar colocar conteúdo importante na área delas ou de articulações, além de poder usar as dobras e articulações como separadores naturais.
Entender se um dispositivo oferece suporte a configurações como a posição de mesa ou de livro pode orientar as decisões sobre o suporte a layouts diferentes ou o fornecimento de recursos específicos.
Informações da janela
No Jetpack Compose, use a collectFoldingFeaturesAsState() função combinável
para observar as informações de dobra da janela.
collectFoldingFeaturesAsState() coleta os recursos de dobra da janela atual
de WindowInfoTracker em um State do Compose que contém uma lista de
FoldingFeature objetos.
Como collectFoldingFeaturesAsState() retorna um State do Compose, os
combináveis são recompostos automaticamente sempre que o estado ou a posição da dobra do dispositivo
muda, sem exigir o gerenciamento manual do ciclo de vida ou a coleta de fluxo:
@Composable
fun FoldAwareScreen() {
val foldingFeatures by collectFoldingFeaturesAsState()
// Access folding features for the current window.
val foldFeature = foldingFeatures.firstOrNull()
if (foldFeature != null) {
// Adapt layout based on the fold feature.
}
}
Recursos de telas dobráveis
A lista de FoldingFeature elementos retornados por
collectFoldingFeaturesAsState() (um subtipo de DisplayFeature)
fornece informações sobre telas dobráveis, incluindo as seguintes
propriedades:
state: o estado dobrado do dispositivo,FLATouHALF_OPENED.orientation: a orientação da dobra ou articulação,HORIZONTALouVERTICAL.occlusionType: indica se a dobra ou articulação oculta parte da tela,NONEouFULLisSeparating: indica se a dobra ou articulação cria duas áreas de exibição lógicas, "true" ou "false".
Um dispositivo dobrável que está HALF_OPENED sempre informa isSeparating como "true" porque a tela é separada em duas áreas de exibição. Além disso, isSeparating é sempre "true" em um dispositivo de tela dupla quando o app abrange as duas telas.
A propriedade FoldingFeature bounds (herdada de DisplayFeature)
representa o retângulo delimitador de um recurso dobrável, como uma dobra ou articulação.
Os limites podem ser usados para posicionar elementos na tela em relação ao recurso:
@Composable
fun FoldFeatureDemo() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
if (foldFeature != null) {
val isSeparating = foldFeature.isSeparating
val occlusionType = foldFeature.occlusionType
val bounds = foldFeature.bounds
// Use bounds and properties to position content.
}
}
Posição de mesa
Usando as informações incluídas no objeto FoldingFeature, o app pode oferecer suporte a posições como a de mesa, em que o smartphone está em uma superfície, a articulação está em uma posição horizontal e a tela dobrável está meio aberta.
A posição de mesa oferece aos usuários a conveniência de operar o smartphone sem segurar o dispositivo nas mãos. A posição de mesa é ótima para assistir conteúdo de mídia, tirar fotos e fazer videochamadas.
Use FoldingFeature.State e FoldingFeature.Orientation de
collectFoldingFeaturesAsState() para determinar se o dispositivo está na posição de mesa
@Composable
fun TabletopContent() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
val isTableTopPosture = foldFeature != null &&
foldFeature.state == FoldingFeature.State.HALF_OPENED &&
foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
if (isTableTopPosture) {
// Tabletop layout: separate content and controls across the fold.
} else {
// Standard layout.
}
}
Como alternativa, você pode determinar se a janela está na posição de mesa verificando a
Posture propriedade retornada por
currentWindowAdaptiveInfoV2():
val adaptiveInfo = currentWindowAdaptiveInfoV2()
val isTabletop = adaptiveInfo.windowPosture.isTabletop
Quando você detectar que o dispositivo está na posição de mesa, atualize o layout do app corretamente. Em apps de mídia, isso normalmente significa colocar a reprodução acima da dobra e posicionar os controles e o conteúdo suplementar logo abaixo para uma experiência de visualização ou escuta viva-voz.
Exemplos
MediaPlayerActivityapp: confira como usar o Exoplayer da Media3 e o WindowManager para criar um player de vídeo com reconhecimento de dobra.Otimize seu app de câmera em dispositivos dobráveis com o Jetpack WindowManager codelab: aprenda a implementar a posição de mesa para apps de fotografia. Mostre o visor na metade de cima da tela (acima da dobra) e os controles na metade de baixo.
Postura de livro
Outro recurso dobrável exclusivo é a posição de livro, em que o dispositivo fica meio aberto com a articulação na vertical. A posição de livro é ótima para ler e-books. Com um layout de duas páginas em uma tela dobrável grande, aberta como um livro encadernado, a posição de livro reproduz a experiência de ler um livro real.
Ele também pode ser usado para fotografia se você quiser capturar uma proporção diferente ao tirar fotos por viva-voz.
Implemente a posição de livro com as mesmas técnicas usadas na posição de mesa. Verifique se a orientação do recurso dobrável é vertical em vez de horizontal:
@Composable
fun BookContent() {
val foldingFeatures by collectFoldingFeaturesAsState()
val foldFeature = foldingFeatures.firstOrNull()
val isBookPosture = foldFeature != null &&
foldFeature.state == FoldingFeature.State.HALF_OPENED &&
foldFeature.orientation == FoldingFeature.Orientation.VERTICAL
if (isBookPosture) {
// Book posture layout: two-page layout across the vertical fold.
} else {
// Standard single-page layout.
}
}
Mudanças no tamanho das janelas
A área de exibição de um app pode mudar devido a uma modificação na configuração do dispositivo. Por exemplo, quando o dispositivo é dobrado, desdobrado, girado ou redimensionado no modo de várias janelas.
Para recuperar a classe de tamanho de janela atual e se adaptar a mudanças de tamanho no Jetpack
Compose, use a função combinável currentWindowAdaptiveInfoV2() da
biblioteca Adaptive do Compose Material 3. currentWindowAdaptiveInfoV2()
retorna uma instância WindowAdaptiveInfo que fornece a
WindowSizeClass da janela atual (com suporte a breakpoints grandes e
extragrandes por padrão), bem como a
windowPosture do dispositivo:
@Composable
fun AdaptiveApp() {
val adaptiveInfo = currentWindowAdaptiveInfoV2()
val windowSizeClass = adaptiveInfo.windowSizeClass
when {
windowSizeClass.isWidthAtLeastBreakpoint(
WIDTH_DP_EXPANDED_LOWER_BOUND
) -> {
// Expanded layout
}
windowSizeClass.isWidthAtLeastBreakpoint(
WIDTH_DP_MEDIUM_LOWER_BOUND
) -> {
// Medium layout
}
else -> {
// Compact layout
}
}
}
Consulte Usar classes de tamanho de janela.
Outros recursos
Para saber mais sobre layouts com reconhecimento de dobra e dispositivos dobráveis, consulte os seguintes recursos:
Amostras
- Exemplo do Jetpack WindowManager (link em inglês): exemplo de como usar a biblioteca WindowManager do Jetpack .
- Jetcaster (link em inglês): implementação da posição de mesa com o Compose.
Codelabs
- Oferecer suporte a dispositivos dobráveis e de duas telas usando a biblioteca do Jetpack WindowManager
- Otimizar o app de câmera em dispositivos dobráveis com o Jetpack WindowManager