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 Pagerを触ってみよう
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Yusaku Tanaka
April 29, 2023
Programming
1.8k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Jetpack Compose Pagerを触ってみよう
Yusaku Tanaka
April 29, 2023
More Decks by Yusaku Tanaka
See All by Yusaku Tanaka
ビジネス向けアプリを開発するときに知っておくべきAndroid Enterpriseの世界
imsaku
1
4k
Managed Configurations - Enterprise向け設定機能を知る
imsaku
0
1.1k
Other Decks in Programming
See All in Programming
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
220
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
280
週末にAI-DLCを本気で回したら$1,600溶けた
hbashimizu
0
130
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
3
440
AIの中の人になってみる
htkym
0
170
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
490
AI時代に学ぶ 好きなルール 嫌いなルール Linter編
shorty5121
0
910
巨大モノリシックアプリ モダン化大作戦
ktcryomm
0
360
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
XHTMLが残したもの
yosuke_furukawa
PRO
2
620
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
190
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
130
Featured
See All Featured
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
540
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
930
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
450
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
270
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.7k
WENDY [Excerpt]
tessaabrams
13
39k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.1k
Transcript
Let’s Try Jetpack Compose Pager DroidKaigi.collect { #2@Fukuoka } saku
(Yusaku Tanaka)
About me saku (Yusaku Tanaka) ・Twitter: @imsaku ・DeNA Co., Ltd.
・佐賀県在住 ・佐賀→福岡→佐賀→福岡→佐賀
Pager
https://github.com/DroidKaigi/conference-app-2022
Compose Foundation 1.4.0~ > Introduce HorizontalPager and VerticalPager, a way
of showing composables in a Pager manner. https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.4.0
Accompanist Pager > This library is deprecated, with official pager
support in androidx.compose.foundation.pager. The original documentation is below the migration guide. https://google.github.io/accompanist/pager/
ただし... ・Pager Indicatorsは引き続きAccompanist側でサポートされている。 ・Compose FoundationにはまだIndicatorsが実装されていない。 ・自分で実装するか、Accompanist Pager Indicatorsを使う。 https://github.com/google/accompanist/pull/1485 https://github.com/google/accompanist/tree/main/pager-indicators
Horizontal Pager
Horizontal Pager
Horizontal Pager @Composable fun BasicHorizontalPager() { Scaffold(...) { padding .>
Column(...) { val pagerState = rememberPagerState() val pageCount = 5 HorizontalPager( pageCount = pageCount, state = pagerState, contentPadding = PaddingValues(16.dp), pageSpacing = 8.dp ) { page .> ... }
Horizontal Pager @Composable fun BasicHorizontalPager() { Scaffold(...) { padding .>
Column(...) { val pagerState = rememberPagerState() val pageCount = 5 HorizontalPager( pageCount = pageCount, state = pagerState, contentPadding = PaddingValues(16.dp), pageSpacing = 8.dp ) { page .> ... }
Horizontal Pager @Composable fun BasicHorizontalPager() { Scaffold(...) { padding .>
Column(...) { val pagerState = rememberPagerState() val pageCount = 5 HorizontalPager( pageCount = pageCount, state = pagerState, contentPadding = PaddingValues(16.dp), pageSpacing = 8.dp ) { page .> ... }
Horizontal Pager @Composable fun BasicHorizontalPager() { Scaffold(...) { padding .>
Column(...) { val pagerState = rememberPagerState() val pageCount = 5 HorizontalPager( pageCount = pageCount, state = pagerState, contentPadding = PaddingValues(16.dp), pageSpacing = 8.dp ) { page .> ... }
Horizontal Pager @Composable fun BasicHorizontalPager() { ... val pagerState =
rememberPagerState() val pageCount = 5 HorizontalPager(...) { page .> Box( modifier = Modifier .background(color = colors.random()) ... ) { Text( text = "$page", ... ) } }
Horizontal Pager @Composable fun BasicHorizontalPager() { ... val pagerState =
rememberPagerState() val pageCount = 5 HorizontalPager(...) { page .> Box( modifier = Modifier .background(color = colors.random()) ... ) { Text( text = "$page", ... ) } }
Horizontal Pager
Pager Indicator
Pager Indicator @Composable fun SimplePagerIndicator(pagerState: PagerState, pageCount: Int) { Row(...)
{ repeat(pageCount) { val color = if (pagerState.currentPage .= it) { Color.DarkGray } else { Color.LightGray } Box( modifier = Modifier.padding(4.dp).clip(CircleShape) .background(color).size(16.dp) ) } } }
Pager Indicator @Composable fun SimplePagerIndicator(pagerState: PagerState, pageCount: Int) { Row(...)
{ repeat(pageCount) { val color = if (pagerState.currentPage .= it) { Color.DarkGray } else { Color.LightGray } Box( modifier = Modifier.padding(4.dp).clip(CircleShape) .background(color).size(16.dp) ) } } }
Pager Indicator @Composable fun SimplePagerIndicator(pagerState: PagerState, pageCount: Int) { Row(...)
{ repeat(pageCount) { val color = if (pagerState.currentPage .= it) { Color.DarkGray } else { Color.LightGray } Box( modifier = Modifier.padding(4.dp).clip(CircleShape) .background(color).size(16.dp) ) } } }
Pager Indicator @Composable fun SimplePagerIndicator(pagerState: PagerState, pageCount: Int) { Row(...)
{ repeat(pageCount) { val color = if (pagerState.currentPage .= it) { Color.DarkGray } else { Color.LightGray } Box( modifier = Modifier.padding(4.dp).clip(CircleShape) .background(color).size(16.dp) ) } } }
Pager Indicator @Composable fun SimplePagerIndicator(pagerState: PagerState, pageCount: Int) { Row(...)
{ repeat(pageCount) { val color = if (pagerState.currentPage .= it) { Color.DarkGray } else { Color.LightGray } Box( modifier = Modifier.padding(4.dp).clip(CircleShape) .background(color).size(16.dp) ) } } }
Horizontal Pager
Pager Animation
Pager Animation
HorizontalPager(...) { page .> Card( modifier = Modifier.fillMaxWidth().height(300.dp) .graphicsLayer {
val pageOffset = ((pagerState.currentPage - page) + pagerState .currentPageOffsetFraction).absoluteValue lerp( start = 0.6f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ).also { scale .> scaleX = scale scaleY = scale } alpha = lerp( start = 0.2f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ) } ) {...}
HorizontalPager(...) { page .> Card( modifier = Modifier.fillMaxWidth().height(300.dp) .graphicsLayer {
val pageOffset = ((pagerState.currentPage - page) + pagerState .currentPageOffsetFraction).absoluteValue lerp( start = 0.6f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ).also { scale .> scaleX = scale scaleY = scale } alpha = lerp( start = 0.2f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ) } ) {...}
HorizontalPager(...) { page .> Card( modifier = Modifier.fillMaxWidth().height(300.dp) .graphicsLayer {
val pageOffset = ((pagerState.currentPage - page) + pagerState .currentPageOffsetFraction).absoluteValue lerp( start = 0.6f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ).also { scale .> scaleX = scale scaleY = scale } alpha = lerp( start = 0.2f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ) } ) {...}
HorizontalPager(...) { page .> Card( modifier = Modifier.fillMaxWidth().height(300.dp) .graphicsLayer {
val pageOffset = ((pagerState.currentPage - page) + pagerState .currentPageOffsetFraction).absoluteValue lerp( start = 0.6f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ).also { scale .> scaleX = scale scaleY = scale } alpha = lerp( start = 0.2f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ) } ) {...}
HorizontalPager(...) { page .> Card( modifier = Modifier.fillMaxWidth().height(300.dp) .graphicsLayer {
val pageOffset = ((pagerState.currentPage - page) + pagerState .currentPageOffsetFraction).absoluteValue lerp( start = 0.6f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ).also { scale .> scaleX = scale scaleY = scale } alpha = lerp( start = 0.2f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ) } ) {...}
Pager Animation
まとめ
まとめ ・Compose Foundation 1.4.0でPagerが導入された ・ただし、Pager Indicatorは実装されていない ・Comose Foundation PagerとAccompanist Pager
Indicatorの併用はできる ・Modifier.graphicsLayerとPagerState.currentPageOffsetFractionを組み合わせて Pagerに視覚エフェクトを実装できる
Let’s Try Jetpack Compose Pager DroidKaigi.collect { #2@Fukuoka } saku
(Yusaku Tanaka)