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
230
3リポジトリーを2ヶ月でモノレポ化した話 / How I turned 3 repositories into a monorepo in 2 months
kubode
0
300
ウォンテッドリーの「ココロオドル」モバイル開発 / Wantedly's "kokoro odoru" mobile development
kubode
2
1.4k
Firebase Dynamic Linksの代替手段を自作する / Create your own Firebase Dynamic Links alternative
kubode
0
780
技術を根付かせる / How to make technology take root
kubode
1
530
WantedlyでのKotlin Multiplatformの導入と課題 / Kotlin Multiplatform Implementation and Challenges at Wantedly
kubode
0
690
Google Play Consoleデベロッパー アカウントの確認 / Verifying your Play Console developer account
kubode
1
1.5k
Make your Android app into Multiplatform app
kubode
0
260
ウォンテッドリーにおけるモバイルアプリ開発 / iOSDC Japan 2024 Sponsor Session
kubode
1
1.6k
Other Decks in Programming
See All in Programming
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
540
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
setup-vp GitLab対応の裏側
naokihaba
0
150
wkhtmltopdfの次どうするか問題2026
willnet
2
1.8k
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
130
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
470
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.4k
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
540
速習iPhone Duo対応
yuukiw00w
2
950
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
250
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
920
A Modern Web Designer's Workflow
chriscoyier
699
190k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
A Soul's Torment
seathinner
8
3.7k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Product Roadmaps are Hard
iamctodd
55
13k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
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.