折りたたみ型デバイス用の Jetpack Window Manager
Jetpack Window Manager には、すべての折りたたみ型デバイスを操作するための標準 API が用意されています。 これには、次の 2 つの重要なクラスが含まれています。
- DisplayFeature - ヒンジや折りたたみなど、連続したフラット スクリーン表面の中断を識別します。 ウィンドウ マネージャーにより、レイアウト変更コールバックから表示機能のコレクションが返されます。
- FoldingFeature - デバイスの特定の機能に関する情報を提供します。 Surface Duo には 1 つの折りたたみ機能しかありませんが、他のデバイスには複数ある場合があります。
同様のガイドが、Android Foldable Codelab にもあります。 折りたたみ型の開発の詳細については、Android のドキュメントを参照してください。Android チームによる例については、GitHub も参照してください。 Jetpack リリース ノートには、更新されると Window Manager の変更が記録されます。
ヒント
Surface Duo デュアルスクリーン ライブラリのコントロールとヘルパー クラスは Window Manager で動作します。 指示に従って、アプリ プロジェクトに適切なパッケージを追加します。
コードで Window Manager を直接使用するには、次の手順を実行します。
依存関係を追加する
最上位の build.gradle ファイルに
mavenCentral()
リポジトリがあることを確認します。allprojects { repositories { google() mavenCentral() } }
モジュールレベル build.gradle ファイルで、
compileSdkVersion
およびtargetSdkVersion
が API 31 以降に設定されていることを確認します。android { compileSdkVersion 31 defaultConfig { targetSdkVersion 31 } ... }
モジュールレベル build.gradle ファイルに次の依存関係を追加します。
Kotlin コードで Window Manager を使用する
Kotlin プロジェクトで Window Manager プロパティにアクセスする場合は、正しい情報フローを設定することが重要です。 そうしないと、受け取るイベント更新プログラムが少なすぎるか、多すぎる場合があり、アプリのパフォーマンスに影響が生じる場合があります。
WindowInfoTracker
オブジェクトを初期化して使用するには、次の手順に従います。
MainActivity クラスで、
WindowInfoTracker
用の変数を作成します。import androidx.window.layout.WindowInfoTracker
がファイルの先頭に追加されていることを確認します。class MainActivity : AppCompatActivity() { private lateinit var windowInfoTracker: WindowInfoTracker
アクティビティの
onCreate
メソッドのWindowInfoTracker
を初期化し、windowLayoutInfo
プロパティから情報を収集するようにフローを設定します。override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialize the window manager windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) // Set up a flow lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowInfoTracker.windowLayoutInfo(this@MainActivity) .collect { // Check FoldingFeature properties here } } } }
次のインポートもファイルの先頭に追加されていることを確認します。
import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch
折りたたみ機能のプロパティの
WindowLayoutInfo
フローを確認するコードを追加します。 このコードが実行されると、(折り目またはヒンジにまたがってスパンされている場合) アクティビティは現在のデバイスの状態と表示機能を使用して更新されます。次のコード スニペットでは、
FoldingFeature
のプロパティに基づいて異なるテキストがアクティビティにより表示されます。この例には、検出された折りたたみ機能のオクルージョン タイプと
isSeparating
値を示すlayout_change_text
と呼ばれる TextView が含まれています。override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { windowInfoTracker.windowLayoutInfo(this@MainActivity) .collect { newLayoutInfo -> layout_change_text.text = "No display features detected" for (displayFeature : DisplayFeature in newLayoutInfo.displayFeatures) { if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.NONE) { layout_change_text.text = "App is spanned across a fold, " + "isSeparating = ${displayFeature.isSeparating}" } if (displayFeature is FoldingFeature && displayFeature.occlusionType == FoldingFeature.OcclusionType.FULL) { layout_change_text.text = "App is spanned across a hinge, " + "isSeparating = ${displayFeature.isSeparating}" } } } } } }
折りたたみ機能のプロパティ
WindowLayoutInfo
クラスには DisplayFeature
項目のコレクションがあります。そのうちの 1 つ以上が FoldingFeature クラスのインスタンスである可能性があります。
折りたたみ機能には、次のプロパティがあります。
bounds
- 折りたたみ機能の外接する四角形の座標occlusionType
- 折りたたみ機能でコンテンツが隠れる場合 (FULL
またはNONE
)orientation
- 折りたたみ機能の向き (HORIZONTAL
またはVERTICAL
)state
- 折りたたみ機能の角度 (HALF_OPENED
またはFLAT
)isSeparating
- 折りたたみ機能によって表示領域が 2 つの異なるセクションに分かれる場合
これらのプロパティに対してクエリを実行して、構成の変更後にレイアウトを調整する方法を決定できます。
isSeparating
コントロールを配置する場所または表示するコンテンツのペインの数を決定する場合は、isSeparating プロパティを使用します。 このフィールドにより、すべての折りたたみ型デバイス上で最適なユーザー エクスペリエンスがアプリで実現されます。
- デュアルスクリーン デバイスの場合、アプリがヒンジにまたがる場合、これは常に当てはまります
- その他の折りたたみ型デバイスの場合、これは、デバイスが卓上ポスチャにあるなど、状態が
HALF_OPENED
の時にのみ当てはまります
isSeparating
プロパティを使用して、折りたたみ型デバイス用にアプリの UI レイアウトを調整するか、分離がない場合は既定の UI を使用するかを決定します。
private fun updateCurrentLayout(newLayoutInfo: WindowLayoutInfo) {
for (displayFeature in newLayoutInfo.displayFeatures) {
val foldFeature = displayFeature as? FoldingFeature
foldFeature?.let {
if (it.isSeparating) {
// The content is separated by the FoldingFeature.
// Here is where you should adapt your UI.
} else {
// The content is not separated.
// Users can see and interact with your UI properly.
}
}
}
}
このフィールドの使用方法の詳細な例については、こちらの isSeparating サンプルを参照してください。
Google でも、このプロパティに関連するドキュメントとサンプルが、大画面および折りたたみ型のガイダンスの一部として提供されています。
サンプル
surface-duo-jetpack-window-manager-samples GitHub リポジトリには、Jetpack Window Manager や従来のビュー システムを使用してビルドされたさまざまなデュアルスクリーン ユーザー エクスペリエンスのパターンを示すいくつかの Kotlin サンプルが含まれています。
また、surface-duo-compose-samples GitHub リポジトリにも、Jetpack Window Manager を使用するデュアルスクリーン Kotlin サンプルが含まれていますが、これらのサンプルでは UI は Jetpack Compose でビルドされています。
Java API
Jetpack Window Manager と Java に関するブログ投稿とこの Java サンプルを参照して、WindowInfoTrackerCallbackAdapter
を介して WindowInfoTracker
クラスにアクセスする方法を確認してください。