Administrador de ventanas de Jetpack para Xamarin
Sugerencia
Los usuarios de Xamarin.Forms deben hacer referencia al NuGet de Xamarin.Forms.DualScreen para la compatibilidad con Surface Duo, con sus DualScreenInfo
clases y TwoPaneView
.
Window Manager de Jetpack está diseñado para desarrolladores que trabajan con Xamarin. Android proyectos.
Window Manager de Jetpack proporciona una API estándar para trabajar con todos los dispositivos plegables. Contiene dos clases importantes:
- DisplayFeature: Identifica las interrupciones en la superficie de la pantalla plana continua, como las bisagras o los pliegues. El Administrador de ventanas devolverá una colección de características de presentación de una devolución de llamada de cambio de diseño.
- FoldingFeature: proporciona información sobre una característica específica del dispositivo; si bien Surface Duo solo tiene una característica de plegado, es posible que otros dispositivos tengan más. La
FoldingFeature
clase proporciona información sobre el estado de esa parte del dispositivo, con propiedades paraBounds
los métodos , yIsSeparating
para , y paraOcclusionType
,Orientation
yState
.
Los ejemplos que usan el Administrador de ventanas de Jetpack están disponibles en el repositorio surface-duo-sdk-xamarin-samples.
Nota
El NuGet de Xamarin.AndroidX.Window.WindowJava está pensado para reemplazar la necesidad de agregar el NuGet de Xamarin.DuoSDK a las aplicaciones de Xamarin.Android.
En lugar de usar la ScreenHelper
clase para determinar IsDualMode
o para GetHingeBoundsDip()
, puede usar los métodos y las propiedades en WindowInfoTracker
y clases relacionadas directamente.
Para usarlo WindowInfoTracker
en el código, siga las instrucciones siguientes (de Xamarin.Android Aplicación de ejemplo del Administrador de ventanas):
Adición de la dependencia
Para agregar el NuGet que proporciona características del Administrador de ventanas de Jetpack:
Haga clic con el botón derecho en Xamarin. Android proyecto y elija Administrar paquetes de NuGet...
Busque Xamarin.AndroidX.Window.WindowJava.
Elija el número de versión más alto para agregar al proyecto (1.0.0.7 es la primera versión estable de la API).
Uso del Administrador de ventanas de Jetpack en el código
En la clase MainActivity , declare una variable para el seguimiento de información de la ventana:
public class MainActivity : AppCompatActivity, IConsumer { WindowInfoTrackerCallbackAdapter wit;
Asegúrese de que las instrucciones y
using AndroidX.Window.Java.Layout;
correctasusing AndroidX.Window.Layout;
se agregan a la parte superior del archivo.Nota
La actividad también implementa
IConsumer
, consulte el paso 4 siguiente para el código delAccept
método requerido por esta interfaz.Inicialice Window Manager en el
OnCreate
de la actividad:protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); wit = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.Companion.GetOrCreate(this));
Ahora cree una función que devuelva una
IExecutor
implementación para proporcionarla a la devolución de llamada como primer parámetro y se invocará mediante ella. Vamos a crear una que se ejecute en el subproceso de la interfaz de usuario, puede crear otra que no se ejecute en el subproceso de la interfaz de usuario si es necesario.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); } }
Defina una clase interna para controlar la devolución de llamada cuando necesite cambiar el diseño. La actividad debe tener un valor TextView denominado
layoutChange
, para que este método pueda actualizar el texto que se muestra: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"); } } }
Nota
La clase
WindowLayoutInfo
tiene una colección de elementosDisplayFeature
, uno o más de los cuales podrían ser instancias deFoldingFeature
. Las instancias de características plegables tienen propiedades paraBounds
yIsSeparating
, y métodos paraOcclusionType
,Orientation
yState
que puede consultar para tomar decisiones sobre cómo ajustar el diseño para el nuevo estado.En una
OnStart
invalidación, registre elAddWindowLayoutInfoListener
controlador y pase el ejecutor y una referencia a la actividad (porque implementaIConsumer
).protected override void OnStart() { base.OnStart(); wit.AddWindowLayoutInfoListener(this, runOnUiThreadExecutor(), this); // first `this` is the Activity context, second `this` is the IConsumer implementation }
No olvide quitar el agente de escucha:
protected override void OnStop() { base.OnStop(); wit.RemoveWindowLayoutInfoListener(this); }
Cuando se ejecute este código, la actividad se actualizará con las características actuales de posición y visualización del dispositivo (si abarcan el pliegue o la bisagra). Agregue código adicional a la devolución de llamada para buscar más información en el objeto
FoldingFeature
.
Muestra
El ejemplo del Administrador de ventanas muestra la información del dispositivo en la pantalla, como se muestra en esta captura de pantalla: