适用于 Xamarin 的 Jetpack 窗口管理器

提示

Xamarin.Forms 用户应引用具有 Surface Duo 支持的 Xamarin.Forms.DualScreen NuGet及其DualScreenInfoTwoPaneView

Jetpack 窗口管理器适用于使用 Xamarin 的开发人员。Android项目。

Jetpack 窗口管理器提供了可用于所有可折叠设备的标准 API。 它包含两个重要的类:

  • DisplayFeature - 标识连续平面(如铰链或折叠)的中断。 窗口管理器将从布局更改回调返回显示功能的集合。
  • FoldingFeature - 提供有关设备的特定功能的信息。虽然 Surface Duo 只有一个折叠功能,但其他设备可能有更多折叠功能。 该FoldingFeature类提供有关设备的该部分的状态的信息,以及设备的属性BoundsIsSeparatingOcclusionTypeOrientation方法以及以及方法State

Surface-duo-sdk-xamarin-samples 存储库中提供了使用 Jetpack 窗口管理器的示例。

注意

Xamarin.AndroidX.Window.WindowJava NuGet旨在替换需要将 Xamarin.DuoSDK NuGet添加到 Xamarin.Android 应用。

可以直接对相关类使用方法和属性WindowInfoTracker,而不是使用ScreenHelper来确定IsDualMode或确定GetHingeBoundsDip()类。

若要在代码中使用WindowInfoTracker,请按照以下说明从 Xamarin.Android (窗口管理器示例应用) :

添加依赖项

添加提供 Jetpack 窗口管理器功能的NuGet:

  1. 右键单击 Xamarin。Android项目并选择“管理NuGet包...”

  2. 搜索 Xamarin.AndroidX.Window.WindowJava

  3. 选择要添加到项目 (1.0.0.7 的最高版本号是 API) 的第一个稳定版本。

在代码中使用 Jetpack 窗口管理器

  1. MainActivity 类中,为窗口信息跟踪器声明变量:

    public class MainActivity : AppCompatActivity, IConsumer
    {
        WindowInfoTrackerCallbackAdapter wit;
    

    确保将正确 using AndroidX.Window.Layout; 语句 using AndroidX.Window.Java.Layout; 和语句添加到文件顶部。

    备注

    该活动还实现 IConsumer,请参阅下面的步骤 4,了解此接口所需的方法的代码 Accept

  2. 初始化活动 OnCreate 中的窗口管理器:

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            wit = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.Companion.GetOrCreate(this));
    
  3. 现在,创建返回实现的函数,以便将其作为第一 IExecutor 个参数提供给回调,并将使用该函数进行调用。 我们要创建一个在 UI 线程上运行的函数,如果需要,你还可以创建一个不在 UI 线程上运行的函数。

    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. 定义内部类,以在需要更改布局时处理回调。 活动应具有一个叫做 layoutChange 的 TextView,使此方法能更新显示的文本:

    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");
            }
        }
    }
    

    注意

    WindowLayoutInfo 类具有一个 DisplayFeature 项的集合,其中的一个或多个项可以是 FoldingFeature 的实例。 折叠功能实例具有属性BoundsIsSeparating方法和方法OcclusionTypeOrientationState可以查询以决定如何调整新状态的布局。

  5. 在替代中OnStartAddWindowLayoutInfoListener,注册处理程序并传递执行程序以及对活动 (的引用,因为它实现了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. 请记住删除侦听器:

    protected override void OnStop()
    {
        base.OnStop();
        wit.RemoveWindowLayoutInfoListener(this);
    }
    
  7. 运行此代码时,活动将更新为当前设备状态并显示功能(如果跨折叠或铰链显示)。 将其他代码添加到回调,查看 FoldingFeature 对象中的其他信息。

示例

窗口管理器示例显示屏幕上的设备信息,如以下屏幕截图所示:

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

资源