折りたたみ型レイアウト
重要
この記事では、パブリック プレビュー段階であり、一般公開前に大幅に変更される可能性がある機能とガイダンスについて説明します。 本書に記載された情報について、Microsoft は明示または黙示を問わずいかなる保証をするものでもありません。
重要
このビューのコンテンツは、アクティビティ ルート ビューがウィンドウにアタッチされた後にのみ使用できます。 これは、実装がウィンドウ マネージャー ライブラリに基づいており、ウィンドウ マネージャーは、ビューがウィンドウにアタッチされている場合にのみ動作しているため発生します。
コンポーネントFoldableLayout
は、折りたたみ型デバイスでアプリケーションを実行するときに、子を別々に配置できるカスタム レイアウトです。 このコンポーネントでは、折りたたみ機能の位置と向きに応じて、画面を 2 つの領域に分割できます。 画面を分割すると、2 つの子コンテナーを横に並べるか上下に並べて保持できます。
シングルスクリーン レイアウト | デュアルスクリーン レイアウト |
---|---|
XML 属性
single_screen_layout_id
- シングル スクリーン モードで表示されるレイアウト ID を受け取ります。dual_screen_start_layout_id
- デュアル スクリーン モードの開始コンテナーに表示されるレイアウト ID を受け取ります。dual_screen_end_layout_id
- デュアル スクリーン モードの開始コンテナーに表示されるレイアウト ID を受け取ります。
FoldableLayout
には、折りたたみ型デバイスでアプリケーションが実行されている場合に 1 つのコンテナーを作成する機能も備わっています。
必要な UI の作成に役立つ次の 4 つの新しい属性が追加されました。
dual_portrait_single_layout_id
- デュアル縦の単一コンテナーについてレイアウト ID を受け取ります。is_dual_portrait_single_container
- デュアル縦の空の単一コンテナーを作成します。dual_landscape_single_layout_id
- デュアル横の単一コンテナーについてレイアウト ID を受け取ります。is_dual_landscape_single_container
- デュアル横の空の単一コンテナーを作成します。
smallestScreenSize のサポート
アクティビティで新しい画面モードに切り替えても、マニフェスト ファイルにフラグ smallestScreenSize
が設定されているために再作成されない場合、レイアウトによって新しい構成が検出され、FoldableLayout の構成に応じて自動的にコンテナーのサイズが変更されるか、2 番目のコンテナーが追加または削除されます。
Android Studio プレビュー
tools_hinge_color
- レイアウト プレビューでのヒンジ カラーを選択します。tools_screen_mode
- レイアウト プレビューでの画面モードを選択します。
XML ファイル内で FoldableLayout にフラグメントを追加する場合、フラグメント UI をプレビューするには次の属性が必要です。
show_in_single_screen
show_in_dual_screen_start
show_in_dual_screen_end
show_in_dual_portrait_single_container
show_in_dual_landscape_single_container
コンテナー ID
コンテナーには、次の ID があります。
first_container_id
second_container_id
画面の向きや特殊な動作がレイアウトに設定されているかどうかには関わりなく、レイアウトが 1 つのコンテナーのみに表示される場合、その ID は first_container_id
になります。 2 つのコンテナーが表示される場合は、second_container_id
も存在します。
たとえば、次のように入力します。
- アプリケーションがシングル スクリーン モードの場合、コンテナー ID は
first_container_id
になります。 - デュアル縦でデュアル スクリーン モードへの切り替えが行われ、
dual_portrait_single_layout_id
またはis_dual_portrait_single_container
を設定している場合、デュアル スクリーン モードでコンテナーが 1 つだけ存在するため、その ID は引き続きfirst_container_id
です。 - デュアル縦への切り替えが行われても、属性
dual_landscape_single_layout_id
およびis_dual_landscape_single_container
を設定していない場合は、IDfirst_container_id
とsecond_container_id
を持つ両方のコンテナーが存在することになります。
コードで FoldableLayout を作成する
findViewById<FrameLayout>(R.id.parent).addView(
FoldableLayout(this, FoldableLayout.Config().apply {
singleScreenLayoutId = R.layout.single_screen
dualScreenStartLayoutId = R.layout.dual_screen_start
dualScreenEndLayoutId = R.layout.dual_screen_end
dualLandscapeSingleLayoutId = R.layout.single_screen
})
)
FoldableLayout 構成を置き換える
次のコードでは、古い構成を破棄し、それを新しいもので置き換えて、新しい構成でビューを生成します。
findViewById<FoldableLayout>(R.id.surface_duo_layout)
.newConfigCreator()
.singleScreenLayoutId(R.layout.single_screen)
.dualScreenStartLayoutId(R.layout.dual_screen_start)
.dualScreenEndLayoutId(R.layout.dual_screen_end)
.reInflate()
FoldableLayout 構成を更新する
次のコードでは、選択した属性を使用して現在の構成を更新し、ビューを生成します。
findViewById<FoldableLayout>(R.id.surface_duo_layout)
.updateConfigCreator()
.dualScreenStartLayoutId(R.layout.dual_screen_start)
.reInflate()
レイアウト コンポーネントの使用方法
アプリケーションを作成するために、アクティビティまたはフラグメントを含むアクティビティを使用して、UI を処理することができます。 フラグメントは、レイアウト リソースファイルで宣言することも、アクティビティで直接作成することもできます。 これらのケースがコンポーネントによってどのように処理されるかについては、後で説明します。
アクティビティの使用
ここでは、UI を処理するアクティビティだけを使用して、コンポーネントがどのように動作するかを見ていきます。
まず、アクティビティの *.xml ファイルに
FoldableLayout
を追加する必要があります。<com.microsoft.device.dualscreen.layouts.FoldableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/enlightened_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true" app:single_screen_layout_id="@layout/single_screen_layout" app:dual_screen_start_layout_id="@layout/single_screen_layout" app:dual_screen_end_layout_id="@layout/dual_screen_end_layout"/>
次に、さまざまな画面モード用に 3 つのレイアウトを作成します。
レイアウトをアクティビティにリンクします。
リソース ファイルで宣言されたフラグメントを使用する
ここでは、*.xml ファイルで宣言されているフラグメントによるコンポーネントの動作について説明します。
まず、アクティビティの *.xml ファイルに
FoldableLayout
を追加する必要があります。<com.microsoft.device.dualscreen.layouts.FoldableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" app:single_screen_layout_id="@layout/single_screen_layout" app:dual_screen_start_layout_id="@layout/dual_screen_start_layout" app:dual_screen_end_layout_id="@layout/dual_screen_end_layout" />
次に、フラグメントを singlescreenlayout.xml、dualscreenstartlayout.xml、および dualscreenendlayout.xml ファイルに宣言します。
<fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/single_list" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.microsoft.device.display.samples.contentcontext.MapPointListFragment" />
レイアウトをアクティビティにリンクします。
アクティビティで作成されたフラグメントの使用
最後に、getSupportFragmentManager().beginTransaction()
を使用して追加されたフラグメントによりコンポーネントがどのように動作するかを説明します。
まず、アクティビティの *.xml ファイルに
FoldableLayout
を追加する必要があります。<com.microsoft.device.dualscreen.layouts.FoldableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" />
これにより、ビューのコンテナーが作成されますが、それらには何も設定されません。
FoldableLayout
のコンテナーには、その ID を使用してアクセスできます。first_container_id
second_container_id
次に、フラグメント マネージャーの状態ハンドラー ライブラリをご覧ください。画面モードの切り替えを処理する際には、フラグメントに特別な注意が必要です。
ビュー バインディング
重要
下のコード スニペットに示すように findViewById を使用してください。 Google ビュー バインディングは使用しないでください。
WindowManager
にウィンドウ レイアウトに関する利用可能な情報がある場合、FoldableLayout
コンテンツは拡張されるため、子インスタンスを取得して使用することはできません。
子ビューをバインドするには、まず FoldableLayout
コンテンツが使用可能な状態であることを確認する必要があります。
このためには、次のメソッドを用いる必要があります。
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val contentChangedListener = object : FoldableLayout.ContentChangedListener {
override fun contentChanged(screenMode: ScreenMode?) {
// Here, you can retrieve the child instance
val child = binding.foldableLayout.findViewById<View>(R.id.child_view)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
override fun onResume() {
super.onResume()
binding.foldableLayout.addContentChangedListener(contentChangedListener)
}
override fun onPause() {
super.onPause()
binding.foldableLayout.removeContentChangedListener(contentChangedListener)
}
}
ここで、
FoldableLayout.ContentChangedListener
は、FoldableLayout
コンテンツが拡張された後に呼び出されるコールバックです。FoldableLayout.addContentChangedListener
は、指定されたFoldableLayout.ContentChangedListener
コールバックを登録します。foldableLayout.removeContentChangedListener
は、指定されたFoldableLayout.ContentChangedListener
コールバックの登録を解除します。
重要
メモリ リークを防ぐため、Activity
または Fragment
の onResume
および onPause
メソッドの内部にこのコードを追加する必要があります。