正規レイアウト

正規化レイアウトは、さまざまなフォーム ファクタで最適なユーザー エクスペリエンスを提供し、さまざまな用途に使用できる実証済みのレイアウトです。

正規化レイアウトが表示されている大画面デバイスの描写。

正規レイアウトは、小画面のスマートフォンのほか、タブレット、折りたたみ式デバイス、ChromeOS デバイスにも対応しています。マテリアル デザインのガイダンスに基づいたレイアウトは、見た目の美しさと機能性を兼ね備えています。

Android フレームワークには特化したコンポーネントが含まれていて、簡単かつ確実にレイアウトを実装できます。

正規化レイアウトを利用することで、生産性を高める魅力的な UI を作成し、優れたアプリの基盤を構築できます。

リスト詳細

リスト / 詳細レイアウトのワイヤフレーム

リストと詳細レイアウトでは、記述や説明などの補足情報(アイテムの詳細情報)があるアイテムのリストをユーザーに表示します。

このレイアウトでは、アプリ ウィンドウが 2 つの横並びのペイン(リスト用と詳細用)に分割されます。ユーザーがリストからアイテムを選択するとそのアイテムの詳細が表示されます。詳細のディープリンクをクリックすると、詳細ペインに追加のコンテンツが表示されます。

拡大幅ディスプレイ(ウィンドウ サイズクラスを使用するを参照)では、リストと詳細を同時に表示できます。リストのアイテムを選択すると詳細ペインが更新され、選択したアイテムに関連するコンテンツが表示されます。

中程度幅ディスプレイとコンパクト幅ディスプレイでは、ユーザーによるアプリの操作に応じてリストまたは詳細のどちらかが表示されます。リストのみが表示されている場合にリストのアイテムを選択すると、リストに代わって詳細が表示されます。詳細だけが表示されているときに [戻る] ボタンを押すと、リストが再表示されます。

デバイスの向きやアプリのウィンドウ サイズなどの設定を変更すると、ディスプレイのウィンドウ サイズクラスが変更されます。リスト / 詳細レイアウトは、設定内容に応じてアプリの状態を維持しながら変更に対応します。

  • リストペインと詳細ペインの両方を表示している拡大幅ディスプレイが中程度幅またはコンパクト幅に狭められた場合、詳細ペインはそのままで、リストペインが非表示になります。
  • 中程度幅またはコンパクト幅のディスプレイに詳細ペインのみが表示されている場合に、ウィンドウ サイズクラスが拡大幅に広げられると、リストと詳細が一緒に表示され、リストペインは、詳細ペイン内のコンテンツに対応するアイテムが選択された状態になります。
  • 中程度幅またはコンパクト幅のディスプレイでリストペインだけが表示されている状態から拡大幅に広げられた場合は、リストペインとプレースホルダの詳細ペインが同時に表示されます。

リストと詳細レイアウトは、メッセージ アプリ連絡先管理ツールインタラクティブなメディア ブラウザのほか、詳細情報を表示するアイテムのリストとしてコンテンツを整理できるアプリに最適です。

図 1. メッセージのリストと選択したメッセージの詳細を表示するメッセージ アプリ

実装

Compose の宣言型パラダイムはウィンドウ サイズクラスのロジックをサポートしていて、リストペインと詳細ペインを同時に表示するか(ウィンドウ サイズクラスが拡大幅の場合)、リストペインまたは詳細ペインのどちらかのみを表示するか(ウィンドウ サイズクラスが中程度幅またはコンパクト幅の場合)を判断します。

データフローを単方向にするために、現在の ウィンドウサイズクラスと、選択したリストアイテム(存在する場合)の詳細を含む、すべての状態をホイスティングします。そうすることで、すべての コンポーザブルがデータにアクセスし、正しくレンダリングできるようになります。

小さいウィンドウに詳細ペインのみを表示している場合は、BackHandler を追加して詳細ペインを削除し、リストペインのみを表示します。BackHandler は、ウィンドウ サイズクラスと選択された詳細の状態に依存するハンドラのため、アプリ全体のナビゲーションには関与しません。

ListDetailPaneScaffold は、リストと詳細レイアウトの実装を簡素化する高レベルのコンポーザブルです。ウィンドウ サイズクラスに基づいてペインのロジックを自動的に処理し、ペイン間のナビゲーションをサポートします。

ListDetailPaneScaffold を使用した最小限の実装を次に示します。

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun MyListDetailPaneScaffold() {
    val navigator = rememberListDetailPaneScaffoldNavigator()
    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            // Listing Pane
        },
        detailPane = {
            // Details Pane
        }
    )
}

この例の主要コンポーネントは次のとおりです。

  • rememberListDetailPaneScaffoldNavigator: リストペインと詳細ペイン間のナビゲーションを管理するナビゲータを作成します。
  • listPane: アイテムのリストを表示します。
  • detailPane: 選択したアイテムのコンテンツを表示します。

実装例の詳細については、以下をご覧ください。

フィード

フィード レイアウトのワイヤフレーム

フィード レイアウトは、同等のコンテンツ要素を設定可能なグリッドに配置して、大量のコンテンツをすばやく簡単に確認できるようにするレイアウトです。

サイズと位置によって、コンテンツ要素間の関係が決まります。

コンテンツ グループは、複数の要素を同じサイズにして一緒に配置したものです。近くの他の要素より大きくすることで、ユーザーの関心を引けます。

カードとリストは、フィード レイアウトの一般的なコンポーネントです。

グリッドは、スクロール可能な単一の列から複数列のフィードまで適応可能なため、フィード レイアウトは、ほぼすべてのサイズのディスプレイに対応できます。

フィードは、特にニュースアプリやソーシャル メディア アプリに適しています。

図 2.さまざまなサイズのカードに投稿を表示するソーシャル メディア アプリ

実装

フィードでは、多数のコンテンツ要素を縦方向にスクロールするコンテナに含め、グリッドに配置します。Lazy リストでは、多数のアイテムを列または行内に効率的にレンダリングできます。Lazy グリッドでは、アイテムをグリッドにレンダリングすることで、アイテムのサイズとスパンを設定しやすくなります。

利用可能な表示領域に基づいてグリッド レイアウトの列を設定し、グリッド アイテムの最小許容幅を決めます。グリッド アイテムを定義する際は、列のスパンを調整して、一部のアイテムを他のアイテムより強調することができます。

セクション ヘッダー、分割線など、フィードの幅いっぱいに表示されるようデザインしたアイテムの場合は、maxLineSpan を使用してレイアウトの幅全体を設定します。

コンパクト幅のディスプレイで複数の列を表示できるだけのスペースがない場合、LazyVerticalGridLazyColumn と同じ動作になります。

LazyVerticalGrid を使用した最小限の実装を次に示します。

@Composable
fun MyFeed(names: List<String>) {
    LazyVerticalGrid(
        // GridCells.Adaptive automatically adapts column count based on available width
        columns = GridCells.Adaptive(minSize = 180.dp),
    ) {
        items(names) { name ->
            Text(name)
        }
    }
}

アダプティブ フィードの鍵は columns 構成です。GridCells.Adaptive(minSize = 180.dp) は、各列の幅が 180.dp 以上のグリッドを作成します。グリッドには、利用可能なスペースに収まるだけの列が表示されます。

実装例については、Compose を利用したフィードのサンプルをご覧ください。

補助ペイン

補助ペイン レイアウトのワイヤフレーム

補助ペイン レイアウトは、アプリのコンテンツをプライマリ表示領域とセカンダリ表示領域に分けて編成するためのものです。

プライマリ表示領域はアプリ ウィンドウの大部分(通常は約 3 分の 2)を占め、メイン コンテンツを表示します。セカンダリ表示領域は、アプリ ウィンドウの残りの部分を構成するペインで、メインのコンテンツをサポートするコンテンツを表示します。

補助ペイン レイアウトは、横向きの拡大幅ディスプレイ(ウィンドウ サイズクラスを使用するを参照)に適しています。中程度幅またはコンパクト幅のディスプレイで表示領域をプライマリとセカンダリに分けられるのは、コンテンツの表示領域が小さくなってもかまわない場合か、最初は追加のコンテンツをボトムシートまたはサイドシートに隠し、メニューまたはボタンで表示を制御できる場合です。

補助ペイン レイアウトとリスト / 詳細レイアウトの違いは、プライマリ コンテンツとセカンダリ コンテンツの関係です。リスト / 詳細レイアウトのセカンダリ ペインのコンテンツは、プライマリ コンテンツと関連していますが、たとえば、補助ペインにツール ウィンドウを表示した場合のように、補助ペイン自体はプライマリ コンテンツとは関係ありません。ただし、リスト / 詳細レイアウトの詳細ペインの補足コンテンツ(例: 商品リスティングの商品説明)は、プライマリ コンテンツがなくても意味を持ちます。

補助ペインのユースケースには、次のようなものがあります。

図 3. 補助ペインに商品の説明が表示されているショッピング アプリ。

実装

Compose 支持窗口大小类别逻辑,可用于确定是同时显示主要内容和辅助内容,还是将辅助内容放置在其他位置。

提升所有状态,包括当前窗口大小类别以及与主要内容和辅助内容中的数据相关的信息。

对于较小宽度的显示屏,可将辅助内容放置在主要内容下方或底部动作条中。对于中等宽度和较大宽度的显示屏,可将辅助内容放置在主要内容旁边,并根据内容和可用空间适当调整辅助内容的大小。对于中等宽度的显示屏,可在主要内容和辅助内容之间平均分配显示空间。对于展开宽度,可为主要内容分配 70% 的空间,并为辅助内容分配 30% 的空间。

SupportingPaneScaffold 是一种高级可组合项,可简化对辅助窗格布局的实现。该可组合函数会根据窗口大小类别自动处理窗格逻辑,在大屏幕上并排显示窗格,或在小屏幕上隐藏辅助窗格。SupportingPaneScaffold 还支持窗格之间的导航。

以下是最低限度的实现:

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun MySupportingPaneScaffold() {
    // Creates and remembers a navigator to control pane visibility and navigation
    val navigator = rememberSupportingPaneScaffoldNavigator()
    SupportingPaneScaffold(
        // Directive and value help control pane visibility based on screen size and state
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        mainPane = {
            // Main Pane for the primary content
        },
        supportingPane = {
            //Supporting Pane for supplementary content
        }
    )
}
示例中的关键组件:

  • rememberSupportingPaneScaffoldNavigator:用于创建导航器以管理窗格可见性(例如,在紧凑型屏幕上隐藏或显示支持窗格)的可组合函数
  • mainPane:用于显示主要内容的可组合项
  • supportingPane:用于显示补充内容的可组合项

如需查看详细的实现示例,请参阅:

参考情報