Xamarin 向け Jetpack Window Manager

ヒント

Xamarin.Forms ユーザーは、Surface Duo サポート用の Xamarin.Forms.DualScreen NuGetとそのクラスをDualScreenInfoTwoPaneView参照する必要があります。

Jetpack Window Manager は、Xamarin を使用する開発者を対象としています。プロジェクトをAndroidします。

Jetpack Window Manager には、すべての折りたたみ型デバイスを操作するための標準 API が用意されています。 これには、次の 2 つの重要なクラスが含まれています。

  • DisplayFeature - ヒンジや折りたたみなど、連続したフラット スクリーン表面の中断を識別します。 ウィンドウ マネージャーにより、レイアウト変更コールバックから表示機能のコレクションが返されます。
  • FoldingFeature - デバイスの特定の機能に関する情報を提供します。Surface Duo には折りたたみ機能が 1 つしかありませんが、他のデバイスにはさらに多くの機能がある可能性があります。 このクラスはFoldingFeature、デバイスのその部分の状態に関する情報を提供します。また、のプロパティBoundsIsSeparatingメソッドOrientationOcclusionTypeStateを指定します。

Jetpack Window Manager を使用したサンプルは、 surface-duo-sdk-xamarin-samples リポジトリで入手できます。

Note

Xamarin.AndroidX.Window.WindowJava NuGetは、Xamarin.DuoSDK NuGetを Xamarin.Android アプリに追加する必要性を置き換えることを目的としています。

クラスをScreenHelper使用して決定IsDualModeまたは決定するGetHingeBoundsDip()代わりに、クラスおよび関連するクラスのメソッドとプロパティをWindowInfoTracker直接使用できます。

コードで使用WindowInfoTrackerするには、以下の手順に従います (Xamarin.Android からWindow Manager サンプル アプリ):

依存関係を追加する

Jetpack Window Manager の機能を提供する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; ファイルの先頭に追加されていることを確認します。

    Note

    アクティビティも実装しています IConsumer。このインターフェイスで必要なメソッドのコードについては、以下の Accept 手順 4 を参照してください。

  2. アクティビティの OnCreate で Window Manager を初期化します。

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

    Note

    WindowLayoutInfo クラスには DisplayFeature 項目のコレクションがあります。そのうちの 1 つ以上が FoldingFeature のインスタンスである可能性があります。 折りたたみ機能インスタンスには、新しい状態に合Boundsわせてレイアウトを調整する方法に関する決定を行うためにクエリを実行するためのプロパティとIsSeparatingメソッドOcclusionTypeOrientationStateがあります。

  5. OnStartオーバーライドでは、ハンドラーをAddWindowLayoutInfoListener登録し、Executor とアクティビティへの参照を渡します (実装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

リソース