Fornecemos uma visão geral do que o futuro suporte a múltiplas janelas no Android N significa para os desenvolvedores e como tirar o melhor proveito dele!
O suporte a várias janelas é um recurso interessante que esperamos no Android N, e há muito tempo que queríamos que estivesse disponível em todos os dispositivos. Porém, para que seja uma experiência agradável, os desenvolvedores podem ter que fazer algumas alterações em seus aplicativos para suportá-lo corretamente.
Uma das sessões do Google I/O foi para os desenvolvedores aprenderem sobre as novas APIs e as mudanças comportamentais do sistema que o suporte a múltiplas janelas traz.
A sessão foi apresentada por Wale Ogunwale, gerente técnico líder do Android ActivityManager e Componentes da estrutura WindowManager – ele e sua equipe são os responsáveis pelas múltiplas janelas no Android.
Você pode assistir o Sessão em modo multijanela no YouTube, mas também fornecemos uma visão geral da sessão aqui.
- Modo de tela dividida: este é o modo disponível por padrão. Como o nome indica, permite abrir dois aplicativos lado a lado.
- Modo de forma livre: os fabricantes podem habilitar isso em dispositivos maiores, o que permite aos usuários redimensionar atividades livremente, além do modo de tela dividida.
- Modo imagem em imagem: voltado para dispositivos Android TV, esse modo é destinado para que players de vídeo sejam executados em uma janela fixada enquanto o usuário interage com outros aplicativos.
android: resizeableActivity
atributo de atividade em seu manifesto para. false
. Isso só deve ser feito se for realmente justificado, pois faz com que seu aplicativo se destaque de maneira negativa por sempre iniciar em modo de tela cheia mesmo se o usuário (ou outro aplicativo) tentar iniciá-lo em várias janelas modo. É importante observar que os atributos de uma atividade raiz se aplicam a todas as atividades dentro da sua pilha de tarefas. Em outras palavras, se você tiver uma atividade que possa ser iniciada por outros aplicativos, certifique-se de que ela suporta o modo multijanela já que você não pode garantir que outros aplicativos iniciarão sua atividade em uma nova tarefa usando. Intent#FLAG_ACTIVITY_NEW_TASK
O suporte ao modo Picture-in-picture deve ser declarado explicitamente por meio do. android: supportsPictureInPicture
atributo. Observe que este atributo é ignorado se. android: resizeableActivity
é. false
Os atributos .Layout podem ser usados para definir dimensões e posicionamento padrão para janelas de formato livre ou para especificar uma largura ou altura mínima para modos de formato livre e tela dividida: -
android: defaultWidth
/android: defaultHeight
: as dimensões padrão da atividade (modo de forma livre). -
android: gravity
: a posição inicial da atividade (modo de forma livre). -
android: minimalWidth
/android: minimalHeight
: as dimensões mínimas da atividade (modos de forma livre e tela dividida)
Compreendendo o ciclo de vida da atividade
O. ciclo de vida da atividade permanece inalterado no modo de múltiplas janelas: Dito isto, algumas diferenças sutis entre os estados de atividade podem resultar em comportamento não intencional que você normalmente não notaria antes de N. É importante saber disso.Activity#onResume()
e. Activity#onPause()
são chamados quando seu aplicativo ganha ou perde o foco, mas não necessariamente quando ele inicia ou deixa de ficar visível. (Lembre-se de que apenas um aplicativo pode ter foco em um determinado momento.) Para aplicativos que atualizam o conteúdo constantemente (por exemplo, reprodução de vídeo), certifique-se de iniciar e interromper atualizações de conteúdo em. Activity#onStart()
e. Activity#onStop()
em vez de. Não fazer isso para aplicativos de vídeo, por exemplo, significará que a reprodução só ocorrerá se o aplicativo estiver focado, o que anula o propósito do modo de múltiplas janelas. O aplicativo oficial do YouTube teve um problema semelhante quando o Android N Developer Preview foi lançado pela primeira vez. Lidando com alterações de tempo de execução
Quando um aplicativo é colocado no modo de múltiplas janelas, algumas configurações do dispositivo serão alteradas. Você pode permitir que sua atividade seja reiniciada (nesse caso. retendo fragmentos pode ser uma boa ideia, se sua atividade precisar realizar uma operação intensiva na inicialização), ou optar por fazê-lo. lidar com as alterações de configuração explicitamente em vez de. Quatro configurações de dispositivos podem mudar ao entrar ou dentro do modo de múltiplas janelas:screenSize
, smallestScreenSize
, screenLayout
e. orientation
. Consulte o. Documentação para desenvolvedores Android para obter mais informações sobre cada atributo, mas observe isso. orientation
não se refere mais à orientação do dispositivo neste caso. Em vez disso, apenas indica se a largura da sua atividade é maior que a altura (paisagem) ou not (retrato). A declaração de que sua atividade irá lidar com essas mudanças pode ser feita a partir do manifesto: android: name=".MyActivity"android: configChanges="screenSize|smallestScreenSize|screenLayout|orientation"/>
Tenha em mente que isso significa que você realmente precisará lidar com essas alterações. Activity#onConfigurationChanged()
, atualizando manualmente as visualizações ou recarregando alguns recursos. Recursos desativados no modo multijanela
Alguns recursos do sistema não serão afetados pelas suas atividades no modo de múltiplas janelas:- Alterações na barra de status e na barra de navegação, como escurecer/ocultar as barras do sistema ou usar o modo imersivo, não terão efeito. Isso faz sentido, pois sua atividade ocupa apenas parte da tela.
- O
android: screenOrientation
O atributo de atividade também não tem efeito no modo multi-janela: como sua atividade será redimensionável, não faz mais sentido que ela tenha uma orientação fixa.
-
Activity#onMultiWindowModeChanged(boolean inMultiWindow)
: chamado quando o estado da atividade muda de tela cheia para múltiplas janelas e vice-versa. -
Activity#onPictureInPictureModeChanged(boolean inPictureOnPicture)
: chamado quando o estado da atividade muda para/do modo PIP. -
Activity#isInMultiWindowMode()
/Activity#isInPictureInPictureMode()
: retorna se a atividade está no modo multi-janela/picture-in-picture ou não. -
Activity#overlayWithDecorCaption(boolean overlay)
: para janelas de formato livre, este método pode ser usado para fazer com que a legenda (a barra usada para arrastar a janela) se sobreponha ao conteúdo em vez de empurrá-lo para baixo.
Activity#overlayWithDecorCaption()
, esses métodos também são fornecidos pelo. Fragment
aula. Iniciando atividades no modo multijanela
-
Activity#enterPictureInPictureMode()
pode ser usado para colocar uma atividade no modo picture-in-picture. Observe que as atividades no modo PiP não são notificadas sobre eventos de entrada – useMediaSession#setMediaButtonReceiver()
se você quiser lidar com tais eventos. Certifique-se também de verificar o site de desenvolvedores Android se estiver interessado em Imagem em imagem no Android N.
- Se o dispositivo estiver no modo de tela dividida, você poderá instruir o sistema a iniciar outra atividade próxima à sua usando o botão
Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT
bandeira. A bandeira não tem efeito se não estiver no modo de tela dividida. - Se o dispositivo estiver no modo de forma livre,
ActivityOptions#setLaunchBounds()
pode ser usado para especificar as dimensões e localização da nova atividade na tela.
Arrastar e soltar
Embora o suporte para arrastar e soltar exista desde o Honeycomb, anteriormente só era possível dentro da mesma atividade. É neve. suportado em múltiplas janelas também. Implementar isso parece ser. basicamente o mesmo de antes, com algumas adições para arrastar e soltar entre atividades:View#startDragAndDrop()
- Novo apelido para
View#startDrag()
. - Para ativar o recurso de arrastar e soltar entre atividades, passe o novo sinalizador
View#DRAG_FLAG_GLOBAL
. - Se você precisar conceder permissões de URI para a atividade do destinatário, passe os novos sinalizadores
View#DRAG_FLAG_GLOBAL_URI_READ
ouView#DRAG_FLAG_GLOBAL_URI_WRITE
, como apropriado.
- Novo apelido para
View#updateDragShadow()
- Substitui a sombra de arrastar por uma operação de arrastar em andamento. Só pode ser chamado pelo aplicativo que originou a operação de arrastar.
View#cancelDragAndDrop()
- Cancela uma operação de arrastar em andamento. Só pode ser chamado pelo aplicativo que originou a operação de arrastar.
- É possível verificar se um dispositivo suporta os modos de forma livre ou picture-in-picture por meio de
PackageManager#hasSystemFeature()
, usandoPackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT
ePackageManager#FEATURE_FREEFORM_PICTURE_IN_PICTURE
respectivamente.
- O
android: windowBackground
O atributo pode ser usado como drawable de fundo, se a atividade estiver sendo redimensionada e sua renderização estiver atrasada. Seandroid: windowBackground
está indefinido,android: windowBackgroundFallback
é usado em seu lugar. Consulte o aplicativo de amostra Multi-Window Playground para obter um exemplo.
- Lidar com mudanças de modo elegantemente:
- Mantenha a consistência da UI independentemente da orientação. Não faça com que os elementos mudem de posição para permitir transições suaves.
- Expandindo o acima, não alterne entre layouts muito diferentes para layouts de telefone/tablet. Em vez disso, adapte o layout do tablet para tamanhos menores para obter consistência.
- Certifique-se de que suas atividades se adaptem a tamanhos pequenos por seguindo os padrões do Material Design.
- Usar
FLAG_ACTIVITY_LAUNCH_ADJACENT
quando faz sentido proporcionar uma experiência mais agradável no modo de tela dividida. - Declarar incompatibilidade de redimensionamento apenas quando justificado. Como discutimos acima, isso faz com que seu aplicativo se destaque de maneira negativa.
- Documentação multijanela.
- Diretrizes do Material Design para modo de tela dividida.
- Exemplo de aplicativo multijanela.