Compatibilidade do tamanho da tela para Chromebooks

A implementação de apps para Android no Chrome OS inclui compatibilidade básica com várias janelas. Em vez de desenhar automaticamente em tela cheia, o Android renderiza apps no Chrome OS em layouts apropriados para o formato.

Redimensionar tarefas e janelas

Como o tamanho da janela da atividade pode mudar, as atividades devem ler a própria resolução no início. As atividades devem reagir às mudanças de resolução chamando onConfigurationChanged(..). Por exemplo, para evitar a perda do trabalho do usuário depois da maximização, siga um destes procedimentos:

  • Processe mudanças de configuração dinamicamente adicionando android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" ao manifesto da atividade.
  • Restaure o estado anterior usando onSaveInstanceState para tornar a transição o mais simples possível. Essa ação é válida quando o pedido de reinicialização é a única escolha.

Ao procurar a configuração atual, use sempre a configuração da atividade atual em getResources().getConfiguration(). Não use a configuração da atividade em segundo plano ou do recurso do sistema. A atividade em segundo plano não tem um tamanho, e a configuração do sistema pode conter várias janelas com tamanhos e orientações conflitantes, impossibilitando a extração de qualquer dado.

Outra consideração importante é que os limites de conteúdo da janela podem mudar. Por exemplo, a área dentro da janela usada pelo app poderá mudar se ela ficar grande demais para a tela. Veja as diretrizes abaixo:

  • Os apps que usam o processo de layout do Android devem ser automaticamente dispostos no espaço disponível.
  • Os apps nativos devem ler a área disponível e monitorar as mudanças de tamanho para evitar a existência de elementos de IU inacessíveis. Chame os métodos a seguir para determinar o tamanho inicial disponível para essa superfície:
    • NativeActivity.mLastContent[X/Y/Width/Height]()
    • findViewById(android.R.id.content).get[Width/Height]()
    O monitoramento contínuo pode ser feito por meio do observador:
    • NativeActivity.onContentRectChangedNative()
    • NativeActivity.onGlobalLayout()
    • Adicione um listener a view.addOnLayoutChangeListener(findViewById(android.R.id.content))
    Se o app pré-dimensionar a arte, deverá fazer isso sempre que a resolução mudar.

O sistema é compatível com redimensionamento livre. No entanto, nem todos os apps foram criados levando-se em conta esse recurso. Veja alguns dos possíveis problemas:

  • Processe corretamente o redimensionamento. O redimensionamento pode ser feito a qualquer momento por vários motivos. Por isso, é muito importante poder salvar e restaurar seu estado da melhor forma possível por meio de onSaveInstanceState caso uma reinicialização seja necessária. Isso também é útil para o Android de maneira geral.
  • Verifique também se a reinicialização da atividade é rápida. Para isso, armazene em cache objetos que você já alocou. Se você não usa os mecanismos de layout do framework (por exemplo, se seu app usa o OpenGL e dimensiona o conteúdo ou se alguma outra lógica é iniciada), ouça eventos onConfigurationChanged para evitar a reinicialização da atividade. Especifique todos os eventos de mudança que podem ser processados dinamicamente.
  • Se você não quer que o redimensionamento seja feito, especifique isso no arquivo de manifesto.
  • É importante observar que o tamanho da janela não é o tamanho da tela e que você provavelmente nunca precisará do tamanho da tela. Para saber o tamanho da janela, use Activity.getResources().getConfiguration().screenWidth e Activity.getResources().getConfiguration().screenHeight em DP.

Para ver sua configuração atual, use sempre o recurso da atividade e extraia a configuração dele. Caso contrário, você acabará vendo "something" como as propriedades da tela.

A posição da tela também pode mudar. Por isso, use sempre o sistema para fazer cálculos de espaço de "janela para tela" ou vice-versa.

Se você já usa o sistema de visualização do Android, a janela deve ser automaticamente posicionada com uma mudança de tamanho.

Se você não usa o sistema de visualização e controla a superfície, seu app precisa processar as mudanças de tamanho por conta própria.

Apps nativos devem usar os membros mLastContent ou recorrer à visualização de conteúdo para saber o tamanho inicial.

Quando o app estiver em execução, ele deverá ouvir eventos onContentRectChangedNative ou onGlobalLayout para reagir às mudanças de tamanho.

Com uma mudança de tamanho, o app deve redimensionar ou recarregar layouts, elementos de arte e atualizar áreas de entrada.

Layout

Para preencher a tela com mais informações, especifique diferentes layouts ou crie o layout dinamicamente para o tamanho solicitado. Normalmente, a geração dinâmica não é recomendada, mas é uma possibilidade.

Os apps que não usam o sistema de layout devem evitar a reinicialização para uma mudança de configuração, porque esse processo pode ser muito caro. Essas mudanças podem acontecer por razões óbvias, como mudanças no tamanho da janela, mas também para motivos não tão evidentes, como uma conversão de modo dispositivo. Mudar de laptop para tablet pode, por exemplo, relatar uma mudança indicando que o teclado físico desapareceu. Uma reinicialização que faz o usuário esperar ou inclusive perder um trabalho inesperadamente não é uma boa experiência.

Verifique se seu código não tenta acessar elementos da IU que foram removidos devido a uma operação de redimensionamento dinâmico.

Monitorar mudanças na hierarquia de visualizações

A adição de uma legenda de controle de janela pode causar alguns problemas. Veja estas recomendações:

  • Não espere que seu conteúdo comece em (0,0) da janela. O conteúdo da janela pode ser deslocado pela altura da legenda. Veja o local da tela da visualização por meio de View.getLocationInWindow() para saber o deslocamento correto.
  • Não espere que a DecorView seja a detentora da contentView. A legenda faz parte da hierarquia da janela e, se existir, estará localizada entre a DecorView e a visualização de conteúdo. Por isso, siga estas orientações:
    • Não mude a hierarquia de visualizações diretamente abaixo da DecorView.
    • Não presuma que a filha da DecorView é do tipo LinearLayout.
  • Não presuma que Configuration.screenHeightDp seja a altura da área de conteúdo do app. Parte dessa altura é ocupada pela visualização de legenda, se existir. O mesmo é válido para Display.getSize() e assim por diante.

Outras considerações

Veja alguns outros aspectos a serem considerados:

  • Se sua atividade deve ser sempre executada em tela cheia, adicione a sinalização android:resizeableActivity="false" ao manifesto.
  • Os usuários finais veem controles de janela para alternar entre todos os layouts disponíveis. Ao escolher a opção de orientação correta, você garante que o usuário tenha o layout certo ao iniciar o app. Se um app estiver disponível nos modos retrato e paisagem, o padrão será paisagem, se possível. Depois de definida, essa opção é memorizada em cada app.
  • Evite mudanças de orientação desnecessárias. Por exemplo, se a orientação da atividade for RETRATO, mas o app chamar setRequestedOrientation(LANDSCAPE) no momento da execução, a janela será redimensionada sem necessidade. Isso é inconveniente para o usuário e poderá causar reinicializações se o app não conseguir processar essa ação. A opção preferencial é definir a orientação uma vez (no manifesto, por exemplo) e mudá-la somente se necessário.
  • Não chame finish() no método onDestroy da sua atividade. Com isso, o app fecha depois do redimensionamento e não é reiniciado, supondo que ele precise da reinicialização.
  • Não use tipos de janela incompatíveis, como TYPE_KEYGUARD e TYPE_APPLICATION_MEDIA.

Observação: recomendamos que você teste seu app para verificar se ele processa as mudanças no tamanho da janela corretamente.