Gerenciador de Janelas do Jetpack para Xamarin

Dica

Os usuários do Xamarin.Forms devem referenciar o NuGet Xamarin.Forms.DualScreen para suporte do Surface Duo, com suas classes e TwoPaneView suas DualScreenInfo classes.

O Gerenciador de Janelas do Jetpack destina-se a desenvolvedores que trabalham com o Xamarin. Android projetos.

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, enquanto o Surface Duo tem apenas um recurso de dobra, é possível que outros dispositivos tenham mais. A FoldingFeature classe fornece informações sobre o estado dessa parte do dispositivo, com propriedades para Bounds e IsSeparating, e métodos para OcclusionType, Orientatione State.

Exemplos usando o Gerenciador de Janelas do Jetpack estão disponíveis no repositório surface-duo-sdk-xamarin-samples.

Observação

O NuGet Xamarin.AndroidX.Window.WindowJava destina-se a substituir a necessidade de adicionar o NuGet Xamarin.DuoSDK aos aplicativos Xamarin.Android.

Em vez de usar a ScreenHelper classe para determinar IsDualMode ou para GetHingeBoundsDip(), você pode usar os métodos e as propriedades em WindowInfoTracker classes relacionadas e diretamente.

Para usar WindowInfoTracker em seu código, siga as instruções abaixo (do Xamarin.Android Aplicativo de exemplo do Gerenciador de Janelas):

Adicionar dependência

Para adicionar o NuGet que fornece recursos do Gerenciador de Janelas do Jetpack:

  1. Clique com o botão direito do mouse no Xamarin. Android projeto e escolha Gerenciar pacotes de NuGet...

  2. Pesquise Xamarin.AndroidX.Window.WindowJava.

  3. Escolha o número de versão mais alto a ser adicionado ao seu projeto (1.0.0.7 é a primeira versão estável da API).

Usar o Gerenciador de Janelas do Jetpack em seu código

  1. Na classe MainActivity , declare uma variável para o rastreador de informações da janela:

    public class MainActivity : AppCompatActivity, IConsumer
    {
        WindowInfoTrackerCallbackAdapter wit;
    

    Verifique se as instruções corretas using AndroidX.Window.Layout; e using AndroidX.Window.Java.Layout; as instruções são adicionadas à parte superior do arquivo.

    Observação

    A atividade também implementa IConsumer, confira a etapa 4 abaixo para o código do Accept método exigido por essa interface.

  2. Inicialize o gerenciador de janelas no OnCreate de sua atividade:

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            wit = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.Companion.GetOrCreate(this));
    
  3. Agora, crie uma função que retorna uma IExecutor implementação para que a forneçamos ao retorno de chamada como o primeiro parâmetro e ela será invocada usando-a. Vamos criar uma que é executada no thread da IU. Você pode criar uma diferente que não seja executada no thread da IU se necessário.

    IExecutor runOnUiThreadExecutor()
    {
        return new MyExecutor();
    }
    class MyExecutor : Java.Lang.Object, IExecutor
    {
        Handler handler = new Handler(Looper.MainLooper);
        public void Execute(IRunnable r)
        {
            handler.Post(r);
        }
    }
    
  4. Defina uma classe interna para manipular o retorno de chamada quando o layout precisar ser alterado. A atividade deve ter um TextView chamado layoutChange para que esse método possa atualizar o texto exibido:

    public void Accept(Java.Lang.Object newLayoutInfo)  // Object will be WindowLayoutInfo
    {
        var newLayoutInfo = (newLayoutInfo as WindowLayoutInfo); // have to cast before use
    
        layoutChange.Text = newLayoutInfo.ToString();
    
        configurationChanged.Text = "One logic/physical display - unspanned";
    
        foreach (var displayFeature in newLayoutInfo.DisplayFeatures)
        {
            var foldingFeature = displayFeature.JavaCast<IFoldingFeature>();
    
            if (foldingFeature != null)
            {
                alignViewToDeviceFeatureBoundaries(newLayoutInfo);
    
                if (foldingFeature.GetOcclusionType() == FoldingFeatureOcclusionType.None)
                {
                    configurationChanged.Text = "App is spanned across a fold";
                }
                if (foldingFeature.GetOcclusionType() == FoldingFeatureOcclusionType.Full)
                {
                    configurationChanged.Text = "App is spanned across a hinge";
                }
                configurationChanged.Text += "\nIsSeparating: " + foldingFeature.IsSeparating
                        + "\nOrientation: " + foldingFeature.Orientation  // FoldingFeatureOrientation.Vertical or Horizontal
                        + "\nState: " + foldingFeature.State; // FoldingFeatureState.Flat or State.HalfOpened
            }
            else
            {
                Log.Info(TAG, "DisplayFeature is not a fold/hinge");
            }
        }
    }
    

    Observação

    A classe WindowLayoutInfo tem uma coleção de itens DisplayFeature, um ou mais dos quais podem ser instâncias de FoldingFeature. As instâncias de recurso dobráveis têm propriedades Boundse IsSeparatingmétodos paraOrientationOcclusionType, e State que você pode consultar para tomar decisões sobre como ajustar seu layout para o novo estado.

  5. Em uma substituição OnStart , registre o AddWindowLayoutInfoListener manipulador e passe o executor e uma referência à atividade (porque ela implementa IConsumer).

    protected override void OnStart()
    {
        base.OnStart();
        wit.AddWindowLayoutInfoListener(this, runOnUiThreadExecutor(), this);
        // first `this` is the Activity context, second `this` is the IConsumer implementation
    }
    
  6. Lembre-se de remover o ouvinte:

    protected override void OnStop()
    {
        base.OnStop();
        wit.RemoveWindowLayoutInfoListener(this);
    }
    
  7. 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 em toda a dobra ou dobradiça). Adicione mais código ao retorno de chamada para verificar se há informações adicionais no objeto FoldingFeature.

Amostra

O exemplo do Gerenciador de Janelas mostra as informações do dispositivo na tela, conforme mostrado nesta captura de tela:

Surface Duo showing Window Manager sample running, and showing device info on the screen

Recursos