Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Jetpack ComposeのBottomSheetとの戦い / Fight with Bo...
Search
Masatoshi Kubode
July 23, 2024
Programming
1.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Jetpack ComposeのBottomSheetとの戦い / Fight with BottomSheet of Jetpack Compose
https://sansan.connpass.com/event/321922/
Masatoshi Kubode
July 23, 2024
More Decks by Masatoshi Kubode
See All by Masatoshi Kubode
AIチャットの改善から見えた、良いAI体験とは / What Constitutes a Good AI Experience: Insights from Improving AI Chat
kubode
0
200
3リポジトリーを2ヶ月でモノレポ化した話 / How I turned 3 repositories into a monorepo in 2 months
kubode
0
280
ウォンテッドリーの「ココロオドル」モバイル開発 / Wantedly's "kokoro odoru" mobile development
kubode
2
1.4k
Firebase Dynamic Linksの代替手段を自作する / Create your own Firebase Dynamic Links alternative
kubode
0
750
技術を根付かせる / How to make technology take root
kubode
1
520
WantedlyでのKotlin Multiplatformの導入と課題 / Kotlin Multiplatform Implementation and Challenges at Wantedly
kubode
0
660
Google Play Consoleデベロッパー アカウントの確認 / Verifying your Play Console developer account
kubode
1
1.4k
Make your Android app into Multiplatform app
kubode
0
250
ウォンテッドリーにおけるモバイルアプリ開発 / iOSDC Japan 2024 Sponsor Session
kubode
1
1.6k
Other Decks in Programming
See All in Programming
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
160
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
150
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
150
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
160
Foundry Localでエージェント開発
seosoft
0
190
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
240
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
240
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
130
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
290
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
370
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
230
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
440
Featured
See All Featured
Building Adaptive Systems
keathley
44
3.2k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Prompt Engineering for Job Search
mfonobong
0
450
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
450
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
570
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
410
30 Presentation Tips
portentint
PRO
1
390
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
240
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
460
Transcript
© 2024 Wantedly, Inc. Jetpack Composeの BottomSheetとの戦い Mobile勉強会#14 2024/07/23 久保出雅俊
© 2024 Wantedly, Inc. wantedly.com/id/kubode @swiz_ard @kubode
© 2024 Wantedly, Inc. Agenda • BottomSheetの苦労話 • 実装については少し難しめの話
© 2024 Wantedly, Inc. Jetpack Composeの標準のBottomSheet実装
© 2024 Wantedly, Inc. 標準のBottomSheet実装 https://m3.material.io/components/bottom-sheets/overview ① Standard ② Modal
Material 2 BottomSheetScaffold ModalBottomSheetLayout Material 3 BottomSheetScaffold ModalBottomSheet
© 2024 Wantedly, Inc. Modalの実装の違い @Composable private fun M3ModalPreview() {
var showSheet by remember { mutableStateOf(false) } Button(onClick = { showSheet = true }) { Text("Show") } if (showSheet) { ModalBottomSheet( onDismissRequest = { showSheet = false } ) { Text("Hello, World!") } } } @Composable private fun M2ModalPreview() { val sheetState = rememberModalBottomSheetState( ModalBottomSheetValue.Hidden ) val coroutineScope = rememberCoroutineScope() ModalBottomSheetLayout( sheetContent = { Text("Hello, World!") }, sheetState = sheetState ) { Button( onClick = { coroutineScope.launch { sheetState.show() } } ) { Text("Show") } } }
© 2024 Wantedly, Inc. 課題
© 2024 Wantedly, Inc. やりたいこと • 検索画面のフィルターをModalで表示 したい • 複数選択のフィルター項目の場合、
OKボタンを画面の下にStickyで出す
© 2024 Wantedly, Inc. 課題 1 BottomNavigationは Activityが所有する XMLのView Activity
BottomNavigation FragmentContainer SearchFragment with Compose
© 2024 Wantedly, Inc. 課題 1 StandardやMaterial2のModalは BottomNavigationが前面に出る (Material3のModalだと問題ないが、現 状はMaterial2を使用
© 2024 Wantedly, Inc. 課題 2 標準のModalの上には、コンテンツを 配置できない
© 2024 Wantedly, Inc. 解決策
© 2024 Wantedly, Inc. 解決策 Modalを自作した • ウィンドウ操作が必要と判断 • ComposeのDialogのコードをもとに自作
◦ Material3のModalじゃない理由は後述しますが、Material3のModalとほぼ同じ実 装
© 2024 Wantedly, Inc. @Composable fun Modal( onDismissRequest: () !>
Unit, sheetContent: @Composable () !> Unit, overlayContent: @Composable (() !> Unit)? = null, sheetState: ModalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden), ) { !/ 色々省略あり val dialog = remember(view) { DialogWrapper(/*省略*/).apply { setContent(composition) { DialogLayout { Box(modifier = Modifier.fillMaxSize()) { ModalLayout( sheetState = sheetState, onDismissRequest = onDismissRequest, sheetContent = sheetContent, ) if (overlayContent != null) { OverlayContent( sheetState = sheetState, overlayContent = overlayContent, ) } } } } } }
© 2024 Wantedly, Inc. @Composable fun Modal( onDismissRequest: () !>
Unit, sheetContent: @Composable () !> Unit, overlayContent: @Composable (() !> Unit)? = null, sheetState: ModalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden), ) { !/ 色々省略あり val dialog = remember(view) { DialogWrapper(/*省略*/).apply { setContent(composition) { DialogLayout { Box(modifier = Modifier.fillMaxSize()) { ModalLayout( sheetState = sheetState, onDismissRequest = onDismissRequest, sheetContent = sheetContent, ) if (overlayContent != null) { OverlayContent( sheetState = sheetState, overlayContent = overlayContent, ) } } } } } } 透明なフルスクリーンウィンドウ
© 2024 Wantedly, Inc. @Composable fun Modal( onDismissRequest: () !>
Unit, sheetContent: @Composable () !> Unit, overlayContent: @Composable (() !> Unit)? = null, sheetState: ModalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden), ) { !/ 色々省略あり val dialog = remember(view) { DialogWrapper(/*省略*/).apply { setContent(composition) { DialogLayout { Box(modifier = Modifier.fillMaxSize()) { ModalLayout( sheetState = sheetState, onDismissRequest = onDismissRequest, sheetContent = sheetContent, ) if (overlayContent != null) { OverlayContent( sheetState = sheetState, overlayContent = overlayContent, ) } } } } } } ウィンドウの中にBottomSheet BottomSheetの制御系
© 2024 Wantedly, Inc. @Composable fun Modal( onDismissRequest: () !>
Unit, sheetContent: @Composable () !> Unit, overlayContent: @Composable (() !> Unit)? = null, sheetState: ModalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden), ) { !/ 色々省略あり val dialog = remember(view) { DialogWrapper(/*省略*/).apply { setContent(composition) { DialogLayout { Box(modifier = Modifier.fillMaxSize()) { ModalLayout( sheetState = sheetState, onDismissRequest = onDismissRequest, sheetContent = sheetContent, ) if (overlayContent != null) { OverlayContent( sheetState = sheetState, overlayContent = overlayContent, ) } } } } } } BottomSheetの前面にオーバーレイ BottomSheetのスクロールには連動 しない→Sticky
© 2024 Wantedly, Inc. Usage @Composable private fun ModalPreview() {
var showSheet by remember { mutableStateOf(false) } Button(onClick = { showSheet = true }) { Text("Show") } if (showSheet) { Modal( onDismissRequest = { showSheet = false }, sheetContent = { Text("Content") }, overlayContent = { Button(/*省略*/) }, ) } }
© 2024 Wantedly, Inc. まとめ • ないものは作る • ソースを読んで理解する ◦
ComposeのWindow関連APIは結構泥臭いことをやってて面白い • 下調べは重要 ◦ 実装時はMaterial3のModalを知らなかった ◦ 知っていれば、もう少し実装時間を減らせたはず
© 2024 Wantedly, Inc.