7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ZOZOAdvent Calendar 2023

Day 12

ListDetailPaneScaffoldを触ってアダプティブ時代に備えよう

Last updated at Posted at 2023-12-12

はじめに

近年のAndroidは、タブレットや折りたたみ式スマホ、車載カーナビ、スマートテレビなど色んな画面サイズが出てきました。
すべての画面サイズに対応しているアプリは中々無いと思いますが、Googleさん的には「対応してほしい!」と思わせるような発表やリリースが相次いでいます。
いずれリジェクト要因として扱われたとき困らないよう、色んな画面サイズに適応できる技術を紹介します!

Material3 Adaptive

Material3配下にMaterial3 Adaptiveというライブラリが追加されました。ここにアダプティブレイアウトとして機能するComposeが入っています。
公式のブログからはNavigationSuiteScaffoldListDetailPaneScaffoldの2つが紹介されていましたが、今回はListDetailPaneScaffoldの使い方をご紹介します。

ListDetailPaneScaffold

ListDetailPaneScaffoldは、リスト用のコンポーザブルと詳細表示用のコンポーザブルを受け取り、一度に1つずつ表示するか、もしくは両方を並べて表示するかという判断ロジックを処理する新しいコンポーザブルです。
正直説明だけだと伝わらないと思うので、とりあえず動かしてみましょう!

まずは導入

以下のimprementionをappモジュールのgradle.buildに追加してください。

implementation 'androidx.compose.material3:material3-adaptive:1.0.0-alpha01'

なお、2023年11月29日に1.0.0-alpha02バージョンが出ていますが、こっちを使うとrememberListDetailPaneScaffoldStateがimportできなくなるので、注意してください。
まぁ、alphaなので細かいことは気にせず進めていきましょう。

compileSdkを変更

最近のAndroidStudioはデフォルトでcompileSdkが33になっていると思いますが、material3-adaptive-android:1.0.0-alpha01は34を要求してきます。

compileSdk 34

ここも変更しておきましょう。

コードを書いて動かしてみる

ありがたいことにシンプルなサンプルコードを公式が提供してくれています。

こちらのコードを使ってビルドすると、こんな感じのリストが出てきました。

ちなみにバグなのかわかりませんが、縦長のレイアウトだとタップしてもなにも起きません。
画面サイズに応じて勝手にレイアウトを調整してくれるコンポーザブルなので、詳細表示画面に遷移してほしいところですね。
まぁ、alphaなので細かいことは気にせず進めていきましょう。(2回目)

気を取り直して横長のレイアウトにして、試しに「Cupcake」をタップしてみると?

20231212_002.png

20231212_003.png

おお〜!詳細画面的なものが右側に出てきましたね!
このように、画面サイズに応じてリスト表示だけにするか、詳細表示も合わせて表示するかを勝手に判断してくれます。

スマートフォンでは画面遷移していたけど、タブレットや横持ちスマートフォンでは画面遷移せずに1画面で表示したい!といった要望を叶えてくれる優れものです。安定版が楽しみですね。

細かい解説

なんとなくListDetailPaneScaffoldの挙動がわかったところで細かい解説です。

まずはこの2行

val state = rememberListDetailPaneScaffoldState()
var selectedItem: MyItem? by rememberSaveable { mutableStateOf(null) }

ListDetailPaneScaffoldStateはまずはListDetailPaneScaffoldの状態を司るものです。
List、Detail、Extraの3つが用意されていて、初期状態はListになっています。
タップされたらDetailに更新して、詳細表示へと移行します。

2行目はタップしたアイテムが何かを通知するためのmutableStateです。

メインどころ

ListDetailPaneScaffold(
    scaffoldState = state,
    listPane = {
        MyList(
            onItemClick = { id ->
                // Set current item
                selectedItem = id
                // Display the details pane
                state.navigateTo(ListDetailPaneScaffoldRole.Detail)
            }
        )
    },
    detailPane = {
        // Show the details pane content if selected item is available
        selectedItem?.let { item ->
            MyDetails(item)
        }
    },
)

さっき作っておいたListDetailPaneScaffoldStateをstateに入れます。
listPaneにはリスト表示のコンポーザブルを、detailPaneには詳細表示のコンポーザブルをそれぞれ入れます。

リスト表示コンポーザブルのonItemClickでListDetailPaneScaffoldState.navigateTo()を使って、詳細表示へと状態遷移するようにしていますね。
シンプルで実装も簡単です!

これで縦長画面サイズの時に、詳細画面遷移が機能してくれたらもっと遊べるんですが。。。
まぁ、alphaなので(略)(n回目)

どうしても縦長画面サイズで詳細表示画面に遷移させたい。。。!

自前の実装でどうにかしている人がいました。
詳しく見ていないですが、安定版が待てない方はチェックしてみてください。

終わりに

明日も@umsysがお送りします。

当日の22時になんとか書き上げたということは。。。?
はい。ネタはこれから考えます。
仕事も普通にありますが、自らを追い込んでいくスタイルで頑張ります。よろしくお願いいたします。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?