Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
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.7k
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
ファインディ株式会社におけるMCP活用とサービス開発
starfish719
0
900
複雑なドメインに挑む.pdf
yukisakai1225
5
1.2k
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
0
450
個人軟體時代
ethanhuang13
0
320
知っているようで知らない"rails new"の世界 / The World of "rails new" You Think You Know but Don't
luccafort
PRO
1
140
旅行プランAIエージェント開発の裏側
ippo012
2
910
rage against annotate_predecessor
junk0612
0
170
Navigating Dependency Injection with Metro
zacsweers
3
260
CloudflareのChat Agent Starter Kitで簡単!AIチャットボット構築
syumai
2
490
ソフトウェアテスト徹底指南書の紹介
goyoki
1
150
Compose Multiplatform × AI で作る、次世代アプリ開発支援ツールの設計と実装
thagikura
0
150
今だからこそ入門する Server-Sent Events (SSE)
nearme_tech
PRO
3
200
Featured
See All Featured
Side Projects
sachag
455
43k
Site-Speed That Sticks
csswizardry
10
810
Building a Scalable Design System with Sketch
lauravandoore
462
33k
A Modern Web Designer's Workflow
chriscoyier
696
190k
Into the Great Unknown - MozCon
thekraken
40
2k
Six Lessons from altMBA
skipperchong
28
4k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
131
19k
Automating Front-end Workflow
addyosmani
1370
200k
How to Think Like a Performance Engineer
csswizardry
26
1.9k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3k
The World Runs on Bad Software
bkeepers
PRO
70
11k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.4k
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