Gerenciador de Janelas do Jetpack para dispositivos dobráveis
O Gerenciador de Janelas do Jetpack fornece uma API padrão para trabalhar com todos os dispositivos dobráveis. Ele contém duas classes importantes:
- DisplayFeature – identifica as interrupções na superfície de tela plana contínua, como dobradiças ou dobras. O Gerenciador de Janelas retornará uma coleção de recursos de exibição de um retorno de chamada de alteração de layout.
- FoldingFeature – fornece informações sobre um recurso específico do dispositivo. Embora o Surface Duo tenha apenas um recurso de dobragem, é possível que outros dispositivos tenham mais.
Um guia semelhante está no Codelab Dobrável para Android. Leia mais sobre como desenvolver para dobráveis nos documentos do Android. Exemplos da equipe do Android também estão disponíveis no GitHub. As notas sobre a versão do Jetpack registram alterações no Gerenciador de Janelas conforme ele é atualizado.
Dica
Os controles e as classes auxiliares na biblioteca de tela dupla do Surface Duo funcionam com o Gerenciador de Janelas. Siga as instruções para adicionar os pacotes corretos ao seu projeto de aplicativo.
Para usar o Gerenciador de Janelas diretamente no seu código, siga as instruções abaixo:
Adicionar dependências
Verifique se você tem o repositório
mavenCentral()
no arquivo build.gradle de nível superior:allprojects { repositories { google() mavenCentral() } }
Verifique se
compileSdkVersion
etargetSdkVersion
estão configurados para a API 31 ou mais recente no seu arquivo build.gradle de nível de módulo:android { compileSdkVersion 31 defaultConfig { targetSdkVersion 31 } ... }
Adicione as seguintes dependências ao arquivo build.gradle de nível de módulo:
Usar o Gerenciador de Janelas em seu código Kotlin
Ao acessar as propriedades do Gerenciador de Janelas nos seus projetos Kotlin, é importante configurar o fluxo correto de informações. Caso contrário, você poderá receber poucas atualizações de eventos ou atualizações demais, e o desempenho do aplicativo poderá ser afetado.
Para inicializar e usar um objeto WindowInfoTracker
, siga as etapas abaixo:
Na classe MainActivity, crie uma variável para o
WindowInfoTracker
. Verifique se oimport androidx.window.layout.WindowInfoTracker
foi adicionado à parte superior do arquivo.class MainActivity : AppCompatActivity() { private lateinit var windowInfoTracker: WindowInfoTracker
Inicialize o
WindowInfoTracker
no métodoonCreate
da sua atividade e configure um fluxo para coletar informações da propriedadewindowLayoutInfo
.override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialize the window manager windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) // Set up a flow lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowInfoTracker.windowLayoutInfo(this@MainActivity) .collect { // Check FoldingFeature properties here } } } }
Verifique se estas importações também estão adicionadas à parte superior do arquivo:
import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch
Adicione o código para verificar se o fluxo
WindowLayoutInfo
tem as propriedades de recurso de dobragem. Quando esse código for executado, a atividade será atualizada com a postura atual do dispositivo e os recursos de exibição (se distribuídos na dobra ou dobradiça).No snippet de código abaixo, a atividade exibe um texto diferente com base nas propriedades de um
FoldingFeature
.Este exemplo tem um TextView chamado
layout_change_text
que mostra o tipo de oclusão e o valorisSeparating
de todos os recursos de dobragem detectados.override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowInfoTracker.windowLayoutInfo(this@MainActivity) .collect { newLayoutInfo -> layout_change_text.text = "No display features detected" for (displayFeature : DisplayFeature in newLayoutInfo.displayFeatures) { if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.NONE) { layout_change_text.text = "App is spanned across a fold, " + "isSeparating = ${displayFeature.isSeparating}" } if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.FULL) { layout_change_text.text = "App is spanned across a hinge, " + "isSeparating = ${displayFeature.isSeparating}" } } } } } }
Propriedades do recurso de dobragem
A classe WindowLayoutInfo
tem uma coleção de itens DisplayFeature
, um ou mais dos quais podem ser instâncias da classe FoldingFeature.
Os recursos de dobragem têm as seguintes propriedades:
bounds
– coordenadas do retângulo delimitador de um recurso de dobragemocclusionType
– informa se um recurso de dobragem oculta o conteúdo (FULL
ouNONE
)orientation
– orientação de um recurso de dobragem (HORIZONTAL
ouVERTICAL
)state
– ângulo de um recurso de dobragem (HALF_OPENED
ouFLAT
)isSeparating
– informa se um recurso de dobragem separa a área de exibição em duas seções distintas
Você pode consultar essas propriedades para tomar decisões sobre como ajustar seu layout após as alterações de configuração.
isSeparating
Ao decidir onde colocar os controles ou quantos painéis de conteúdo mostrar, use a propriedade isSeparating. Esse campo garante que o seu aplicativo forneça a melhor experiência do usuário em todos os dispositivos dobráveis:
- Para dispositivos de tela dupla, isso sempre será verdadeiro quando um aplicativo for distribuído pela dobradiça
- Para outros dispositivos dobráveis, isso só será verdadeiro quando o estado for
HALF_OPENED
, como quando um dispositivo estiver na horizontal
Use a propriedade isSeparating
para decidir se deseja adaptar o layout da interface do usuário do aplicativo para um dispositivo dobrável ou usar a interface do usuário padrão quando não houver separação:
private fun updateCurrentLayout(newLayoutInfo: WindowLayoutInfo) {
for (displayFeature in newLayoutInfo.displayFeatures) {
val foldFeature = displayFeature as? FoldingFeature
foldFeature?.let {
if (it.isSeparating) {
// The content is separated by the FoldingFeature.
// Here is where you should adapt your UI.
} else {
// The content is not separated.
// Users can see and interact with your UI properly.
}
}
}
}
Para ver um exemplo mais elaborado de como usar esse campo, confira este exemplo de isSeparating.
O Google também fornece documentação e exemplos relacionados a essa propriedade como parte das diretrizes dele sobre dispositivos dobráveis e de tela grande.
Exemplos
O repositório do GitHub surface-duo-jetpack-window-manager-samples contém vários exemplos de Kotlin que demonstram diferentes padrões de experiência do usuário de tela dupla criados usando o Gerenciador de Janelas do Jetpack e o sistema de exibição tradicional.
O repositório GitHub surface-duo-compose-samples também tem exemplos de Kotlin de tela dupla que usam o Gerenciador de Janelas do Jetpack, mas nestes exemplos a interface do usuário é criada com o Jetpack Compose.
API Java
Veja a postagem no blog sobre Gerenciador de Janelas do Jetpack com Java e esse exemplo do Java para ver como acessar a classe WindowInfoTracker
por meio do WindowInfoTrackerCallbackAdapter
.
Recursos
- Referência de API androidx.window.layout
- Exemplos da equipe do Android
- Dar suporte a novos fatores forma com a nova biblioteca do Gerenciador de Janelas do Jetpack
- Vídeo: como desenvolver para dobráveis
- Exemplo de Codelab do Gerenciador de Janelas (GibHub)
- Log de mudanças do Gerenciador de Janelas do Jetpack.