Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Jetpack Composeで 様々な画面サイズに対応する/With Jetpack Com...
Search
t_takahiro
January 23, 2024
Programming
0
1.8k
Jetpack Composeで 様々な画面サイズに対応する/With Jetpack Compose Adapt to various screen sizes
2024/1/23開催 ZOZO Tech Meetup Androidの発表資料です。
t_takahiro
January 23, 2024
Tweet
Share
Other Decks in Programming
See All in Programming
モダンJSフレームワークのビルドプロセス 〜なぜReactは503行、Svelteは12行なのか〜
fuuki12
0
190
ID管理機能開発の裏側 高速にSaaS連携を実現したチームのAI活用編
atzzcokek
0
190
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
8
19k
FluorTracer / RayTracingCamp11
kugimasa
0
200
Integrating WordPress and Symfony
alexandresalome
0
130
dnx で実行できるコマンド、作ってみました
tomohisa
0
140
WebRTC と Rust と8K 60fps
tnoho
2
1.9k
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
140
connect-python: convenient protobuf RPC for Python
anuraaga
0
360
堅牢なフロントエンドテスト基盤を構築するために行った取り組み
shogo4131
6
2k
AIコーディングエージェント(Gemini)
kondai24
0
160
宅宅自以為的浪漫:跟 AI 一起為自己辦的研討會寫一個售票系統
eddie
0
480
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.6k
Building Applications with DynamoDB
mza
96
6.8k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.5k
Agile that works and the tools we love
rasmusluckow
331
21k
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
Building Adaptive Systems
keathley
44
2.9k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Docker and Python
trallard
46
3.7k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
960
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
54k
Transcript
Jetpack Composeで 様々な画面サイズに対応する 株式会社ZOZO ブランドソリューション開発本部 FAANS部 フロントエンドブロック 田中 崇裕
Copyright © ZOZO, Inc. 1
© ZOZO, Inc. 株式会社ZOZO ブランドソリューション開発本部 FAANS部 フロントエンドブロック 田中 崇裕 •
2023年10月中途入社 • 3年日記をもう少しで書き終えます 2
© ZOZO, Inc. 3 目次 1. 様々な画面サイズに対応することについて 2. WindowSizeClassを用いた実装 3.
その他の手法 4. まとめ
© ZOZO, Inc. 4 1 様々な画面サイズに対応することについて 実情 • なかなか優先度が高くない •
色々な形や大きさの端末があって気にしていたらキリがない
© ZOZO, Inc. 5 1 様々な画面サイズに対応することについて 実情 • なかなか優先度が高くない •
色々な形や大きさの端末があって気にしていたらキリがない しかし • Androidプラットフォームは様々な端末にアプローチしやすい • 市場にモバイル以外の端末が増えてきている
© ZOZO, Inc. 6 1 様々な画面サイズに対応することについて 実情 • なかなか優先度が高くない •
色々な形や大きさの端末があって気にしていたらキリがない しかし • Androidプラットフォームは様々な端末にアプローチしやすい • 市場にモバイル以外の端末が増えてきている 対応することについて • UX向上に少なからず繋がるはず • いま対応するかはさておき、いずれ対応が必要になった時に心理的ハードルが低く なっていることが大事
© ZOZO, Inc. 7 2 WindowSizeClassを用いた実装 2-1 対応する画面サイズの定義 2-2 事前準備
2-3 実装例 (ナビゲーション、ペイン)
© ZOZO, Inc. 8 2-1 対応する画面サイズの定義 マテリアルデザインで分類されている3つのサイズに対して対応する (heightにも同じ定義があるが今回はwidthを使用) https://codelabs.developers.google.com/jetpack-compose-adaptability?hl=en#2
© ZOZO, Inc. 9 2-1 対応する画面サイズの定義 マテリアルデザインで分類されている3つのサイズに対して対応する (heightにも同じ定義があるが今回はwidthを使用) →WindowSizeClassを用いれば簡単に分岐が可能 https://codelabs.developers.google.com/jetpack-compose-adaptability?hl=en#2
© ZOZO, Inc. 10 2-2 事前準備 依存関係を追加 dependencies { implementation
"androidx.compose.material3:material3-window-size-class:1.1.0" }
© ZOZO, Inc. 11 2-2 事前準備 端末の横幅を取得する @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) override fun
onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { ReplyTheme { val windowSize = calculateWindowSizeClass(this) ReplyApp(windowSize.widthSizeClass) } } }
© ZOZO, Inc. 12 2-2 事前準備(補足) @Previewで別々の端末サイズを指定可能 @Preview(showBackground = true,
widthDp = 700) @Composable fun ReplyAppPreviewTablet() { ReplyTheme { ReplyApp( replyHomeUIState = ReplyHomeUIState(,,,), windowSize = WindowWidthSizeClass.Medium ) } }
© ZOZO, Inc. 13 2-2 事前準備(補足) AndroidStudio>Tools>DeviceManager>CreateDvices>Resizable(Experimental)をAPI33で作成
© ZOZO, Inc. 14 2-3 実装例 端末サイズによって以下の出し分けを実施する • ナビゲーション •
ペイン
© ZOZO, Inc. 15 2-3 実装例(ナビゲーション) ナビゲーションの種類 • Bottom Navigation
• Navigation Rail • NavigationDrawer ◦ Modal Navigation Drawer ◦ Permanent Navigation Drawer
© ZOZO, Inc. 16 2-3 実装例(ナビゲーション) ナビゲーションの種類 • Bottom Navigation
• Navigation Rail • NavigationDrawer ◦ Modal Navigation Drawer ◦ Permanent Navigation Drawer
© ZOZO, Inc. 17 2-3 実装例(ナビゲーション) ナビゲーションの種類 • Bottom Navigation
• Navigation Rail • NavigationDrawer ◦ Modal Navigation Drawer ◦ Permanent Navigation Drawer
© ZOZO, Inc. 18 2-3 実装例(ナビゲーション) ナビゲーションの種類 • Bottom Navigation
• Navigation Rail • NavigationDrawer ◦ Modal Navigation Drawer ◦ Permanent Navigation Drawer enum class ReplyNavigationType { BOTTOM_NAVIGATION, NAVIGATION_RAIL, PERMANENT_NAVIGATION_DRAWER }
© ZOZO, Inc. 19 2-3 実装例(ナビゲーション) @Composable fun ReplyApp( windowSize:
WindowWidthSizeClass, ) { val navigationType = when (windowSize) { WindowWidthSizeClass.Compact -> ReplyNavigationType.BOTTOM_NAVIGATION WindowWidthSizeClass.Medium -> ReplyNavigationType.NAVIGATION_RAIL WindowWidthSizeClass.Expanded -> ReplyNavigationType.PERMANENT_NAVIGATION_DRAWER else -> ReplyNavigationType.BOTTOM_NAVIGATION } ReplyNavigationWrapperUI(navigationType) }
© ZOZO, Inc. 20 2-3 実装例(ナビゲーション) @Composable private fun ReplyNavigationWrapperUI(
navigationType: ReplyNavigationType, ) { if (navigationType == ReplyNavigationType.PERMANENT_NAVIGATION_DRAWER) { PermanentNavigationDrawer( drawerContent = { PermanentDrawerSheet { NavigationDrawerContent() //これは自分で作成 } } ) { ReplyAppContent(navigationType) //さらに子に渡す } }
© ZOZO, Inc. 21 2-3 実装例(ナビゲーション) } else { ModalNavigationDrawer(
drawerContent = { ModalDrawerSheet { NavigationDrawerContent() //これは自分で作成 } }, ) { ReplyAppContent(navigationType) //さらに子に渡す } }
© ZOZO, Inc. 22 2-3 実装例(ナビゲーション) @Composable fun ReplyAppContent( navigationType:
ReplyNavigationType, ) { Row(,,,) { AnimatedVisibility(visible = navigationType == ReplyNavigationType.NAVIGATION_RAIL) { ReplyNavigationRail() //これは自分で作成 } Column(,,,) { ReplyListOnlyContent() AnimatedVisibility(visible = navigationType == ReplyNavigationType.BOTTOM_NAVIGATION) { ReplyBottomNavigationBar() //これは自分で作成 } } } }
© ZOZO, Inc. 23 2-3 実装例(ペイン) ペインとは → 区画のこと 1つ 2つ
© ZOZO, Inc. enum class ReplyContentType { LIST_ONLY, LIST_AND_DETAIL }
24 2-3 実装例(ペイン) ペインとは → 区画のこと LIST_ONLY LIST_AND_DETAIL
© ZOZO, Inc. 25 2-3 実装例(ペイン) @Composable fun ReplyApp( windowSize:
WindowWidthSizeClass, ) { val contentType = when (windowSize) { WindowWidthSizeClass.Compact -> ReplyContentType.LIST_ONLY WindowWidthSizeClass.Medium -> ReplyContentType.LIST_ONLY WindowWidthSizeClass.Expanded -> ReplyContentType.LIST_AND_DETAIL else -> ReplyContentType.LIST_ONLY } ReplyNavigationWrapperUI(contentType) // ReplyContent()に渡すのみ }
© ZOZO, Inc. 26 2-3 実装例(ペイン) @Composable fun ReplyAppContent( contentType:
ReplyContentType, ) { Row(,,,) { Column(,,,) { if (contentType == ReplyContentType.LIST_AND_DETAIL) { ReplyListAndDetailContent() //これは自分で作成 } else { ReplyListOnlyContent() //これは自分で作成 } } } }
© ZOZO, Inc. 27 3 その他の手法 3-1 ListDetailPaneScaffold 3-2 NavigationSuiteScaffold
※どちらもalpha版 https://medium.com/androiddevelopers/new-apis-for-adaptive-layouts-in-jetpack-compose-f27cace48bcd
© ZOZO, Inc. 28 3-1 ListDetailPaneScaffold ListDetailPaneScaffold( ,,, listPane =
{ MyList(,,,) }, detailPane = { MyDetails(,,,) }, ) https://medium.com/androiddevelopers/new-apis-for-adaptive-layouts-in-jetpack-compose-f27cace48bcd implementation "androidx.compose.material3:material3-adaptive-android:1.0.0-alpha01"
© ZOZO, Inc. 29 3-2 NavigationSuiteScaffold NavigationSuiteScaffold( navigationSuiteItems = {
navItems.forEachIndexed {,,, -> item( icon = {,,,}, label = {,,,}, selected = ,,,, onClick = {,,,} ) } } ) { // Screen content. Text(,,,) } https://medium.com/androiddevelopers/new-apis-for-adaptive-layouts-in-jetpack-compose-f27cace48bcd implementation "androidx.compose.material3:material3-adaptive-navigation-suite-android:1.0.0-alpha01"
© ZOZO, Inc. 30 4 まとめ • 様々な画面サイズに対応する場合、対応する形を最初に決める • 画面サイズ対応する際はWindowSizeClassのコールバックを活用する
• 取得したサイズごとにナビゲーションやペインを出し分けることで対応 • 今後、より実装しやすくなることに期待
None