适用于 Xamarin 的 Jetpack 窗口管理器
提示
Xamarin.Forms 用户应引用具有 Surface Duo 支持的 Xamarin.Forms.DualScreen NuGet及其DualScreenInfo
类TwoPaneView
。
Jetpack 窗口管理器适用于使用 Xamarin 的开发人员。Android项目。
Jetpack 窗口管理器提供了可用于所有可折叠设备的标准 API。 它包含两个重要的类:
- DisplayFeature - 标识连续平面(如铰链或折叠)的中断。 窗口管理器将从布局更改回调返回显示功能的集合。
- FoldingFeature - 提供有关设备的特定功能的信息。虽然 Surface Duo 只有一个折叠功能,但其他设备可能有更多折叠功能。 该
FoldingFeature
类提供有关设备的该部分的状态的信息,以及设备的属性Bounds
IsSeparating
和OcclusionType
Orientation
方法以及以及方法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:
右键单击 Xamarin。Android项目并选择“管理NuGet包...”
搜索 Xamarin.AndroidX.Window.WindowJava。
选择要添加到项目 (1.0.0.7 的最高版本号是 API) 的第一个稳定版本。
在代码中使用 Jetpack 窗口管理器
在 MainActivity 类中,为窗口信息跟踪器声明变量:
public class MainActivity : AppCompatActivity, IConsumer { WindowInfoTrackerCallbackAdapter wit;
确保将正确
using AndroidX.Window.Layout;
语句using AndroidX.Window.Java.Layout;
和语句添加到文件顶部。备注
该活动还实现
IConsumer
,请参阅下面的步骤 4,了解此接口所需的方法的代码Accept
。初始化活动
OnCreate
中的窗口管理器:protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); wit = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.Companion.GetOrCreate(this));
现在,创建返回实现的函数,以便将其作为第一
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); } }
定义内部类,以在需要更改布局时处理回调。 活动应具有一个叫做
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
的实例。 折叠功能实例具有属性Bounds
和IsSeparating
方法和方法OcclusionType
,Orientation
State
可以查询以决定如何调整新状态的布局。在替代中
OnStart
AddWindowLayoutInfoListener
,注册处理程序并传递执行程序以及对活动 (的引用,因为它实现了IConsumer
) 。protected override void OnStart() { base.OnStart(); wit.AddWindowLayoutInfoListener(this, runOnUiThreadExecutor(), this); // first `this` is the Activity context, second `this` is the IConsumer implementation }
请记住删除侦听器:
protected override void OnStop() { base.OnStop(); wit.RemoveWindowLayoutInfoListener(this); }
运行此代码时,活动将更新为当前设备状态并显示功能(如果跨折叠或铰链显示)。 将其他代码添加到回调,查看
FoldingFeature
对象中的其他信息。
示例
窗口管理器示例显示屏幕上的设备信息,如以下屏幕截图所示: