Com o modo janela para computador, os usuários podem executar vários apps simultaneamente em janelas redimensionáveis para ter uma experiência versátil, semelhante à de um computador.
Na figura 1, é possível ver a organização da tela com o Modo Janela para Computador ativado. Observações:
- Os usuários podem executar vários apps lado a lado simultaneamente.
- A barra de tarefas fica em uma posição fixa na parte de baixo da tela, mostrando os apps em execução. Os usuários podem fixar apps para acesso rápido.
- Uma nova barra de cabeçalho personalizável decora a parte de cima de cada janela com controles como minimizar e maximizar.
Por padrão, os apps são abertos em tela cheia nos tablets Android. Para iniciar um app no Modo Janela para Computador, toque e pressione a alça da janela na parte de cima da tela e arraste a alça na interface, conforme mostrado na Figura 2.
Quando um app está aberto no modo janela para computador, outros apps também são abertos em janelas para computador.
Os usuários também podem invocar o modo janela para computador no menu que aparece abaixo da alça da janela ao tocar ou clicar nela ou usar o atalho de teclado tecla Meta (Windows, Command ou Pesquisa) + Ctrl + Seta para baixo.
Para sair do modo janela para computador, feche todas as janelas ativas ou arraste a alça da janela na parte de cima de uma janela para computador para a parte de cima da tela. O atalho de teclado Meta + H também sai do redimensionamento de janelas da área de trabalho e executa os apps em tela cheia novamente.
Para voltar ao modo janela para computador, toque ou clique no bloco do espaço de trabalho na tela "Recentes".
Redimensionamento e modo de compatibilidade
No Modo Janela para Computador, os apps com orientação bloqueada podem ser redimensionados livremente. Isso significa que, mesmo que uma atividade esteja bloqueada na orientação retrato, os usuários ainda podem redimensionar o app para uma janela de orientação paisagem.
Os apps declarados como não redimensionáveis (ou seja, resizeableActivity = false) têm
a interface dimensionada, mantendo a mesma proporção.
Os apps de câmera que bloqueiam a orientação ou são declarados como não redimensionáveis têm um tratamento especial para os visores: a janela é totalmente redimensionável, mas o visor mantém a mesma proporção. Ao presumir que os apps sempre são executados no modo retrato ou paisagem, eles fixam no código ou fazem outras suposições que levam a cálculos incorretos da orientação ou da proporção da visualização ou da imagem capturada, resultando em imagens esticadas, de lado ou de cabeça para baixo.
Enquanto os apps não estiverem prontos para implementar visores de câmera totalmente responsivos, o tratamento especial vai oferecer uma experiência do usuário mais básica que mitiga os efeitos que suposições erradas podem causar.
Para saber mais sobre o modo de compatibilidade para apps de câmera, consulte Modo de compatibilidade do dispositivo.
Encaixes de cabeçalho personalizáveis
Todos os apps em execução no modo de janela para computador têm uma barra de cabeçalho, mesmo no modo imersivo. É possível personalizar essa barra para evitar que o conteúdo do app seja obscurecido e para desenhar elementos personalizados da interface diretamente no espaço do cabeçalho.
Implementação
Para desenhar conteúdo personalizado na barra de cabeçalho, a primeira etapa é deixar o fundo da barra de cabeçalho transparente. Para isso, use a flag
APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND com o
WindowInsetsController.
window.insetsController?.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND, WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND )
Depois que a barra de cabeçalho ficar transparente, você poderá estilizar a área de cabeçalho para corresponder ao design do seu
app. Use WindowInsets.isCaptionBarVisible para detectar se a barra está
presente e aplique a altura ou o padding adequado ao seu layout.
@OptIn(ExperimentalLayoutApi::class) @Composable fun CaptionBar() { if (WindowInsets.isCaptionBarVisible) { Row( modifier = Modifier .windowInsetsTopHeight(WindowInsets.captionBar) .fillMaxWidth() .background(if (isSystemInDarkTheme()) Color.White else Color.Black), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { Text( text = "Caption Bar Title", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(4.dp) ) } } }
setSystemBarsAppearance(appearance,mask): configura o estilo visual das barras de sistema. O primeiro parâmetro define as flags de aparência de destino, enquanto o segundo atua como uma máscara para controlar quais flags específicas são modificadas.windowInsetsTopHeight(): define automaticamente a altura do seu combinável para corresponder à barra de cabeçalho do sistema, ajudando seu plano de fundo personalizado a preencher a área de legenda sem codificar valores de pixels.WindowInsets.captionBar: fornece as dimensões dos controles de modo janela para computador (Fechar, Maximizar etc.), permitindo que a interface seja dimensionada ou ocultada automaticamente ao entrar ou sair do modo janela para computador.
Para mais informações, consulte Sobre encartes de janela. Além de um título, você pode mostrar outros elementos da interface na barra de legenda, como guias (como no Google Chrome), barras de pesquisa ou avatares de perfil.
Interface do usuário
Para evitar a sobreposição da sua interface com botões do sistema, o Android 15 oferece o método
WindowInsets#getBoundingRects(). O método retorna uma lista de objetos
Rect que representam áreas ocupadas por elementos do sistema. O espaço restante na barra de legenda é uma zona de segurança em que você pode colocar conteúdo personalizado com segurança.
Alterne a aparência dos elementos de legenda do sistema para temas claros e escuros usando
APPEARANCE_LIGHT_CAPTION_BARS. Acesse encartes usando
WindowInsets.Companion.captionBar() no Compose ou
WindowInsets.Type.captionBar() no Views.
Para mais informações, consulte Sobre encartes de janela.
Suporte a multitarefas e várias instâncias
A multitarefa é a base do Modo Janela para Computador, e permitir várias instâncias do seu app pode aumentar muito a produtividade dos usuários.
A partir do Android 15, você pode usar
PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI. Ao definir essa propriedade no
AndroidManifest.xml, você especifica que a interface do sistema precisa fornecer opções
(como um botão "Nova janela") para que o app seja iniciado em várias instâncias.
<application>
<property
android:name="android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"
android:value="true" />
</application>
Observação:no modo janela para computador e outros ambientes de várias janelas, novas tarefas são abertas em uma nova janela. Por isso, verifique a jornada do usuário sempre que seu app iniciar várias tarefas.
Gerenciar instâncias de apps com gestos de arrastar
No modo de várias janelas, os usuários podem iniciar uma nova instância de app arrastando um elemento da interface (como uma guia ou um documento) para fora da janela do app. Os usuários também podem mover elementos entre diferentes instâncias do mesmo app.
Transferir dados arrastando e soltando
Para configurar um elemento combinável como uma origem de arrastar para arrastar e soltar de várias instâncias,
permitindo que os usuários arrastem conteúdo para outra instância do seu app ou criem uma
nova instância soltando conteúdo em uma área vazia da tela, use o
modificador dragAndDropSource. Na lambda, retorne DragAndDropTransferData, transmitindo o ClipData que contém os dados a serem transferidos e flags para configurar o comportamento de várias instâncias.
O Android 15 apresenta duas flags importantes para o modo janela no estilo computador e interações de várias instâncias:
DRAG_FLAG_GLOBAL_SAME_APPLICATION: indica que uma operação de arrastar pode cruzar limites de janela (para várias instâncias do mesmo aplicativo). QuandostartDragAndDrop()é chamado com essa flag definida, apenas janelas visíveis pertencentes ao mesmo aplicativo podem participar da operação de arrastar e receber o conteúdo arrastado.
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( clipData = ClipData.newPlainText("label", "Your data"), flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION ) }
DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG: permite que os usuários iniciem uma nova instância do app soltando o conteúdo arrastado em uma área vazia da tela, se nenhuma outra janela processar a ação de soltar.- Ao usar essa flag, você precisa fornecer um
IntentSenderusandoClipData.Item.Builder#setIntentSender(), que o sistema usa para iniciar a nova atividade se ocorrer uma soltura não processada.
- Ao usar essa flag, você precisa fornecer um
Modifier.dragAndDropSource { _ -> val intent = Intent.makeMainActivity(activity.componentName).apply { putExtra("EXTRA_ITEM_ID", itemId) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK or Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT } val pendingIntent = PendingIntent.getActivity( activity, 0, intent, PendingIntent.FLAG_IMMUTABLE ) val data = ClipData( "Item $itemId", arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT), ClipData.Item.Builder().setIntentSender(pendingIntent.intentSender).build() ) DragAndDropTransferData( clipData = data, flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION or View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG, ) }
Receber dados transferidos
Para aceitar dados de outra instância, use o modificador dragAndDropTarget.
É necessário solicitar permissões explicitamente se os dados vierem de uma instância ou app diferente.
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.toAndroidDragEvent().clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { requestDragAndDropPermissions(activity, event.toAndroidDragEvent()) val clipData = event.toAndroidDragEvent().clipData val item = clipData?.getItemAt(0)?.text if (item != null) { // Process the dropped text item here } return item != null } } )
Etapas principais:
- Filtro: use
shouldStartDragAndDroppara verificar se os dados recebidos (tipo MIME) são compatíveis. - Permissões: chame
requestDragAndDropPermissions(event)para acessar os dados. - Processar: extraia os dados no callback
onDrop.
Otimizações adicionais
Personalize as inicializações de apps e faça a transição dos apps do modo janela para computador para tela cheia.
Especificar tamanho e posição padrão
Nem todos os apps, mesmo que redimensionáveis, precisam de uma janela grande para oferecer valor ao usuário. Você
pode usar o método ActivityOptions#setLaunchBounds() para especificar um tamanho
e uma posição padrão quando uma atividade é iniciada.
Entrar no modo de tela cheia no espaço de trabalho
Os apps podem entrar em tela cheia chamando Activity#requestFullScreenMode(). O método mostra o app em tela cheia diretamente do modo de janela para computador.