Introduce Material Motion library that can be used in Jetpack Compose. ๐ŸŽญ

These days, there are many people who are interested in Jetpack Compose. Most of them seem to be learning through articles or code labs organized in Android Developers, or by making simple samples. The same goes for me.

However, there are some things I canโ€™t know in detail, so Iโ€™m going to tackle one of those things. Apps usually divide UI tasks into screen units. Today, I will look at how to implement transition effects in Jetpack Compose.

Many apps use bottom tab UX.

Bottom Navigation with no transition

Writing with Jetpack Compose is simple.

Scaffold(bottomBar = { ... }) { innerPadding ->

Jetpack Compose์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Material Motion ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๐ŸŽญ

์š”์ฆ˜ Jetpack Compose์— ๊ด€์‹ฌ์„ ๊ฐ€์ง€๋Š” ๋ถ„๋“ค์ด ๋งŽ์€๋ฐ์š”. ๋Œ€๋ถ€๋ถ„์€ Android Developers์— ์ •๋ฆฌ๋œ ๊ธ€์ด๋‚˜ ์ฝ”๋“œ๋žฉ์„ ํ†ตํ•ด์„œ, ํ˜น์€ ๊ฐ„๋‹จํ•œ ์ƒ˜ํ”Œ์„ ๋งŒ๋“ค์–ด๋ณด๋ฉด์„œ ํ•™์Šตํ•˜๊ณ  ๊ณ„์‹ค ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ €๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๊ตฌ์š”.

ํ•˜์ง€๋งŒ ์ž์„ธํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒƒ๋„ ๊ตฐ๋ฐ๊ตฐ๋ฐ ๋ณด์—ฌ์„œ, ๊ทธ๋Ÿฐ ๊ฒƒ๋“ค ์ค‘์— ํ•œ๊ฐ€์ง€๋ฅผ ๋‹ค๋ฃฐ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. ์•ฑ์€ ๋ณดํ†ต ํ™”๋ฉด ๋‹จ์œ„๋กœ UI ์ž‘์—…์„ ๋‚˜๋ˆ„๊ฒŒ ๋˜๋Š”๋ฐ์š”. ์˜ค๋Š˜์€ Jetpack Compose์—์„œ ํ™”๋ฉด ์ „ํ™˜ ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ์•ฑ์—์„œ ํ•˜๋‹จ ํƒญ ํ˜•ํƒœ์˜ UX๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Bottom Navigation with no transition

Compose๋กœ ์ž‘์„ฑํ•˜๋ฉด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

Scaffold(bottomBar = { . โ€ฆ

๋ ˆ์ด์•„์›ƒ XML์„ Jetpack Compose๋กœ ์ „ํ™˜ํ•ด๋ณด์ž.

Jetpack Compose Beta ๋ฒ„์ „์ด ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰

๊ทธ๋™์•ˆ์€ Alpha ๋‹จ๊ณ„๋ผ์„œ API๊ฐ€ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”๋ฐ์š”. ์ด์ œ๋Š” API๊ฐ€ ์ •๋ฆฌ๋˜์–ด Jetpack Compose๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ ์ข‹์€ ์‹œ์ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. (Jetpack ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฐ ๋‹จ๊ณ„๊ฐ€ ์–ด๋–ค ์ฐจ์ด์ ์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹  ๋ถ„์€ ๊ณต์‹๋ฌธ์„œ๋ฅผ ๋ณด์„ธ์š”.)

ํ•™์Šตํ•  ๋ถ€๋ถ„์ด ๋งŽ์ง€๋งŒ, ์‹œ์ž‘์€ ๊ฐ€๋ฒผ์šด ๋‚ด์šฉ์œผ๋กœ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ง€๊ธˆ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋ ˆ์ด์•„์›ƒ XML์„ Jetpack Compose์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋ณธ ๊ธ€์€ Compose 1.0.0-beta01์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฆโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ€ฆ

2021๋…„์—๋Š” ์ข€ ๋” ๋‚˜์•„์ง€๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค ๐Ÿ™

์–ด๋Š์ƒˆ ์˜ฌํ•ด๋„ ํ›Œ์ฉ ์ง€๋‚˜๋ฒ„๋ ธ๋‹ค.
์ž‘๋…„์—๋Š” ํšŒ๊ณ  ๊ธ€์„ ์ ์ง€ ์•Š์•˜์ง€๋งŒ, ์˜ฌํ•ด๋Š” (์‹ฌ์‹ฌํ•˜๋‹ˆ๊นŒ) ๋˜๋Œ์•„๋ณธ๋‹ค. ๐Ÿ˜„

์—…๋ฌด ํ™˜๊ฒฝ์˜ ๋ณ€ํ™” ๐Ÿ 

๊ทผ๋ฐฉ์˜ ๋‹ค๋ฅธ ํšŒ์‚ฌ์™€ ๋™์ผํ•˜๊ฒŒCOVID-19๋กœ ์ธํ•ด, ์ ์ง„์ ์œผ๋กœ ์ง‘์—์„œ ์ถœํ‡ด๊ทผํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ํ•˜๋ฃจ์ข…์ผ ์•‰์•„์žˆ์–ด์•ผ ํ•˜๋‹ˆ๊นŒ, ํ‰์†Œ๋ผ๋ฉด ์‚ฌ์ง€ ์•Š์„ ๋น„์‹ผ ์˜์ž๋„ ํ•˜๋‚˜ ๊ตฌ๋งคํ–ˆ๋‹ค โ€” ๋‹ค๋“ค ๊ตฌ๋งคํ•˜์…จ์ฃ ? ๐Ÿคฃ โ€” ๊ทธ๋ž˜๋„ ์ž‘์€ ๋…ธํŠธ๋ถ ํ™”๋ฉด์— ์ ์‘ํ•˜๋Š” ๊ฒƒ์ด ์‰ฝ์ง€๋Š” ์•Š์•˜๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๐Ÿ‘€

์ฝ”๋กœ๋‚˜๊ฐ€ ๋œ ์‹ฌํ•  ๋•Œ๋Š” ๊ฐ€๋” ์ถœ๊ทผํ•˜๊ณ , ํšŒ์‚ฌ์—์„œ๋„ ์ž‘์€ ์ด๋ฒคํŠธ๋ฅผ ์ค€๋น„ํ•ด์ค˜์„œ ์ฆ๊ฑฐ์šด ์‹œ๊ฐ„๋„ ์žˆ์—ˆ๋‹ค. ์ง‘์—์„œ ๊ณต๋ถ€ํ•˜๋ ค๋Š” ์ƒ๊ฐ์œผ๋กœ ์ฑ…๋„ ์ž‘๋…„๋ณด๋‹ค 2๋ฐฐ ์ด์ƒ ๋งŽ์ด ์ƒ€๋‹ค. ์—ด์‹ฌํžˆ ์ฝ์ง€๋Š” ์•Š์•„์„œ ๋ฐ˜์„ฑ์ด ๋œ๋‹ค. ๐Ÿ“š

๊พธ์ค€ํ•œ ๋ฐœํ‘œ ์ฐธ์—ฌ ๐Ÿง‘โ€๐Ÿ’ป

์ž‘๋…„์—๋Š” ๋งŽ์€ ๊ฐœ๋ฐœํ–‰์‚ฌ๋“ค์ด ์˜คํ”„๋ผ์ธ์œผ๋กœ ์—ด๋ ธ์—ˆ๊ณ , ๋‚˜๋„ โ€ฆ


2์ฃผ ์ „๋ถ€ํ„ฐ ์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์ž ๋ถ„๋“ค์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” 2020 ๋“œ๋กœ์ด๋“œ๋‚˜์ด์ธ  ํ–‰์‚ฌ๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ž‘๋…„๊ณผ ๋‹ค๋ฅด๊ฒŒ ์˜ฌํ•ด๋Š” ๋ชจ๋‘ ์˜จ๋ผ์ธ์œผ๋กœ ์ง„ํ–‰๋˜๋ฉฐ, ๋งค ์ฃผ๋งˆ๋‹ค 3๊ฐœ์˜ ์„ธ์…˜ ์˜์ƒ์„ ๊ณต์‹ YouTube ์ฑ„๋„์„ ํ†ตํ•ด ๊ณต๊ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ์ฃผ์— ์ œ ์˜์ƒ์ด ์˜ฌ๋ผ์™”๋Š”๋ฐ์š”. ์ฃผ์ œ ๋•Œ๋ฌธ์ธ์ง€ ๋ฐ˜์‘์ด ๋ณ„๋กœ ์—†๋Š” ๋Š๋‚Œ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ๋“ ๋“  ์ƒ๊ฐ์ด ์˜์ƒ์ด ๋„ˆ๋ฌด ๋”ฑ๋”ฑํ•ด์„œ ๊ทธ๋Ÿฐ๊ฒŒ ์•„๋‹Œ๊ฐ€ ์‹ถ์–ด์„œ ๊ธ€๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. (๐Ÿ‘€ ํ•‘๊ณ„ํ•˜๊ณ ๋Š”!)

๊ทธ๋Ÿผ ๋‚ด์šฉ์„ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿš€

๋ฐœํ‘œ ์ฃผ์ œ๋ฅผ Animation์œผ๋กœ ์ •ํ•œ ๊ฒƒ์€ ๋‘๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ๋Š”๋ฐ์š”. ๊ทธ๋™์•ˆ์˜ ๋“œ๋กœ์ด๋“œ๋‚˜์ด์ธ  ์„ธ์…˜์—์„œ๋Š” Animation์„ ๋‹ค๋ฃฌ ์ ์ด ์—†์—ˆ๋˜ ๊ฒƒ ๊ฐ™์•˜๊ณ , ๊ทธ๋ž˜์„œ ์•ฑ UX/UI๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ โ€ฆ

Android์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  LifecycleOwner๋ฅผ ์ •๋ฆฌํ•ด๋ด…๋‹ˆ๋‹ค.

์š”์ฆ˜์—๋Š” Android ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— Kotlin Coroutines ์‚ฌ์šฉ์„ ์ข€ ๋” ์„ ํ˜ธํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. Kotlin์ด ๊ธฐ๋ณธ ์–ธ์–ด๋กœ ์ข€ ๋” ์ต์ˆ™ํ•ด์ง€๊ธฐ๋„ ํ–ˆ๊ณ , AndroidX์—์„œ ์ œ๊ณตํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ Component๊ฐ€ Coroutines์„ ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ์ตœ๊ทผ์—๋Š” Kotlin ๋งŒ์œผ๋กœ ์ž‘์„ฑ๋œ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์†์† ์ถ”๊ฐ€๋˜๊ณ  ์žˆ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿค”

์˜ค๋Š˜์€ ์ด๋Ÿฐ Android ๊ฐœ๋ฐœํ™˜๊ฒฝ์˜ ๋ณ€ํ™” ์†์—์„œ Kotlin Coroutines์„ ์ข€ ๋” ์†์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„์ง€ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ ์ „์—

Android์—์„œ ์–ด๋–ค ์ž‘์—…์ด ์˜ค๋žœ ์‹œ๊ฐ„ Main โ€ฆ


์ง€๋‚œ ์ฃผ์— ๋Œ€ํ•™์ƒ/์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž ๋ถ„๋“ค์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” 2020 NAVER ํ…Œํฌ์ฝ˜์„œํŠธ ์˜จ๋ผ์ธ ํ–‰์‚ฌ๊ฐ€ ์—ด๋ ธ์Šต๋‹ˆ๋‹ค. ํ˜„์—…์˜ ๊ฐœ๋ฐœ์ž๋ถ„๋“ค์ด ๋‚ด์šฉ์„ ์ค€๋น„ํ•˜์—ฌ ์ง„ํ–‰๋˜์—ˆ๊ณ , ์ €๋„ ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ์š”. ์˜์ƒ์œผ๋กœ๋งŒ ๋‚จ๊ธฐ๊ธฐ์— ์กฐ๊ธˆ ์•„์‰ฌ์šด ๋งˆ์Œ์ด ๋“ค์–ด ํ–‰์‚ฌ์—์„œ ๋ฐœํ‘œํ•œ ๋‚ด์šฉ ์ผ๋ถ€๋ฅผ ๊ธ€๋กœ ์˜ฎ๊ฒจ๋ดค์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿš€

โ€œ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์„ ๋งŒ๋“œ๋ ค๋ฉด JAVA๋งŒ ์•Œ๋ฉด ๋˜๋‚˜์š”?โ€

์ฒ˜์Œ ๊ฐœ๋ฐœํ•ด๋ณด๋ ค๊ณ  ํ•˜๋Š” ๋ถ„๋“ค์ด ์ข…์ข… ์ด๋Ÿฐ ์งˆ๋ฌธ์„ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ์š”. Java๋งŒ ํ•ด๋„ ์–ด๋Š์ •๋„ ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค๋งŒ, ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” Java ์™ธ์—๋„ XML ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , ๊ฒฝ์šฐ์— ๋”ฐ๋ผ์„œ๋Š” C++ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

์ตœ๊ทผ์—๋Š” ๋Œ€๋ถ€๋ถ„ Java ๋Œ€์‹  Kotlin ์ฝ”๋“œ๋ฅผ โ€ฆ

์•„์ง Stable์ด ๋˜์ง€ ์•Š์€ AndroidX์˜ ๋‹ค์Œ feature๋“ค์„ ํ›‘์–ด๋ด…๋‹ˆ๋‹ค.

์–ด๋Š์ƒˆ 6์›”์ด ์ฝ” ์•ž์œผ๋กœ ์„ฑํผ ๋‹ค๊ฐ€์™€์„œ, ์ƒ๋ฐ˜๊ธฐ์— ์–ด๋–ค ๊ฒƒ๋“ค์ด ๊ฐœ๋ฐœ๋˜๊ณ  ์žˆ๋Š”์ง€ ์‚ดํŽด๋ดค์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์˜ฌํ•ด ๋ง๊นŒ์ง€๋Š” stable๋กœ ๋ฐฐํฌ๋˜์ง€ ์•Š์„๊นŒ์š”? ๐Ÿค”

์‹œ์ž‘ํ•˜๊ธฐ ์•ž์„œ, ๋ณธ ๊ธ€์€ ์—ฌ๋Ÿฌ feature๋“ค์˜ ์†Œ๊ฐœ ์ •๋„๋กœ ๊นŠ์€ ๋‚ด์šฉ๊นŒ์ง€ ๋‹ค๋ฃจ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ž˜ ์ •๋ฆฌ๋œ ๋ธ”๋กœ๊ทธ ๋งํฌ๋„ ํ•จ๊ป˜ ์ฒจ๋ถ€ํ•˜๋‹ˆ, ์ž์„ธํ•œ ๋‚ด์šฉ์ด ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ๋งํฌ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”. ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! ๐Ÿ‘ป


์•ž์œผ๋กœ๋Š” View์—์„œ ๊ฐ์ข… Owner์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ViewTreeViewModelStoreOwner
  • ViewTreeSavedStateRegist โ€ฆ

Introduce how to implement Neumorphism on Android ๐ŸŒˆ

Iโ€™ve seen several posts on Neumorphism design since the end of last year. Personally, Iโ€™m interested in a new design, so I wanted to apply it to Android. However, I couldnโ€™t find the library because of platform restrictions maybe. So I made it simple. (Github Repository)

I wrote this article to share the library and get more feedback. ๐Ÿคฃ

Before starting, Some of you may be unfamiliar with the term Neumorphism. Itโ€™s a UI concept like Material Design, and there is a difference in drawing shadows. If you want to know more about Neumorphism, read the article below.

In Materialโ€ฆ

์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ neumorphism์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๐ŸŒˆ

์ž‘๋…„ ๋ง๋ถ€ํ„ฐ Neumorphism ๋””์ž์ธ์— ๋Œ€ํ•œ article์„ ์ ‘ํ•˜์‹  ๋ถ„๋“ค์ด ์žˆ์„ํ…๋ฐ์š”. ๊ฐœ์ธ์ ์œผ๋กœ ์ƒˆ๋กœ์šด ๋””์ž์ธ์— ๊ด€์‹ฌ์ด ๋™ํ•ด์„œ, Android์— ์ ์šฉํ•ด๋ณด๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”Œ๋žซํผ ์ œ์•ฝ์‚ฌํ•ญ ๋•Œ๋ฌธ์ธ์ง€? ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์–ด์„œ ์ง์ ‘ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ๋ดค์Šต๋‹ˆ๋‹ค. (Github Repository)

ํ˜ผ์ž๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š”, ๊ณต์œ ํ•˜๊ณ  ๋‹ค์–‘ํ•œ ์˜๊ฒฌ์„ ๋ฐ›์•„๋ณด๋ฉด ์žฌ๋ฏธ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์„œ ๊ธ€์„ ์ ์–ด๋ด…๋‹ˆ๋‹ค. ๐Ÿคฃ

์‹œ์ž‘ํ•˜๊ธฐ ์•ž์„œ, Neumorphism์ด๋ผ๋Š” ์šฉ์–ด๊ฐ€ ์ƒ์†Œํ•˜์‹  ๋ถ„๋“ค๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ์š”. Material Design ๊ฐ™์€ UI ์ปจ์…‰์œผ๋กœ, ๊ทธ๋ฆผ์ž๋ฅผ ๊ทธ๋ฆฌ๋Š” ๋ถ€๋ถ„์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ( โ€ฆ


Android Developer in South Korea.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store