์์
๊ธฐ์กด ํ๋ก์ ํธ๋ ์์ง๋ deprecated ๋ jcenter repository์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์ฐ๊ณ ์๋ค. Gradle 8.0์ ๊ธฐ๋ฅ์ ์จ์ ํ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์ jcenter์ ๋ฌผ๋ฆฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ๊ต์ฒดํด์ผ ํ๋ค.
๊ต์ฒด ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ExpandedRecyclerView๋ฅผ ์ ๊ณตํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค. ์ฑ์์ ๋ง์ด ์ฐ์ด๋ ๊ธฐ๋ฅ๋ ์๋๊ณ , ์ฝ๊ด ์ค๋ช ์ ์ํด ๊ฐ๋จํ ์ฐ์ด๋ ๊ฒ ๋ฟ์ด๋ผ์ ์ง์ ๋ง๋ค๊ธฐ๋ก ํ๋ค.
Compose๋ก ๋ง๋๋ ๊ฒ ๋ ๊ฐ๋จํ ๊ฒ ๊ฐ์์ ์์ํ๋ค.
Gradle ์ค์
build.gradle ํ์ผ ์ค์ ์ ํ๋ค.
์ ๋ง ํ์ํ dependency๋ง ์ถ๊ฐํ๋ ค๊ณ ํ๋ค.
์ฝ์ง ํฌ์ธํธ๋ค์ด ์๋ค.
android {
...
buildFeatures {
...
compose = true
}
composeOptions {
// ์ฝ์ง ํฌ์ธํธ 1 : ์ ๋ฒ์ ์ ์ฌ์ฉํ๋ ์ฝํ๋ฆฐ ๋ฒ์ ์ ๋ง์ถฐ์ผ ํ๋ค.
kotlinCompilerExtensionVersion '1.3.1'
}
}
dependencies {
...
// Compose
def compose_version = "1.3.3"
implementation 'androidx.activity:activity-compose:1.6.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
// ์ฝ์ง ํฌ์ธํธ 2 : Preview๋ฅผ ์ํด ํ์ํ๋ค.
implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
// ์ฝ์ง ํฌ์ธํธ 3 : LazyColumn์ ์ฐ๊ธฐ ์ํด ํ์ํ๋ค.
implementation "androidx.compose.material:material:1.3.1"
}
์ฝ์ง ํฌ์ธํธ 1
์ฒ์์ kotlinCompilerExtensionVersion ๋ฒ์ ์ '1.1.1'๋ก ๋ง์ท๋ค. ์์ ์ฌ๋ ค๋ ์ฐธ์กฐํ ๋ธ๋ก๊ทธ์์ ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ ํ ๋ฒ์ ์ด์๋ค.
Build๊ฐ Fail ๋๊ณ , ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๋ฅผ ๋ฐ๊ฒฌํ๋ค.
e: This version (1.1.1) of the Compose Compiler requires Kotlin version 1.6.10 but you appear to be using Kotlin version 1.7.10 which is not known to be compatible. Please fix your configuration (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).
Compose Compiler ๋ฒ์ ์ด 1.1.1์ธ๋ฐ Kotlin version์ด 1.6.1์ด ์๋๊ณ 1.7.10์ด๋ผ์ ๋ฌธ์ ๊ฐ ๋๋ค๊ณ ํ๋ค. '๋ด๊ฐ ๊ฒฝ๊ณ ์ํ๋ค๊ณ ๋งํ์ง ๋ง๋ผ!'๋ ํ๋ฑ์ง๊ฐ ๋ด๊ธด ์๋ฌ๋ผ ์ธ์๊น์๋ค.
๊ทธ๋์ ์ฐพ์๋ดค๋ค.
1.1.1 ์์ 1.3.1๋ก ์์ ํ๋ ๋น๋๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ด๋ค์ก๋ค.
์ฝ์ง ํฌ์ธํธ 2
Compose Preview๋ฅผ ์ํด์๋ dependency๊ฐ ํ์ํ๋ค. ์ฝ์งํ๋ฉด์ ์ 3์ค์ด ํ์ํ๋ค๋ ๊ฒ์ ์์๋ค.
์ฝ์ง ํฌ์ธํธ 3
RecyclerView ๋์ LazyColumn์ ์ฐ๊ณ ์ ํ๋๋ฐ, LazyColumn์ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐพ์ ์๊ฐ ์์๋ค. ๋ค๋ฅธ ์ปดํฌ์ฆ ํ๋ก์ ํธ์์ LazyColum์ ํจํค์ง๋ฅผ ํ์ธํ๋ค.
ํ๋ก์ ํธ์ ์์ androidx.compose.foundation ํจํค์ง๊ฐ ์กด์ฌํ์ง ์์๋ค.
๊ฒ์ํด๋ณด๋ Compose Foundation ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ๊ณตํ๊ณ ์์๋ค.
https://developer.android.com/jetpack/androidx/releases/compose-foundation
์ฌ๊ธฐ์ ๊ณ ๋ฏผํ๋ ๊ฒ์ด, ์ compose foundation๋ง์ ์ถ๊ฐํ ๊ฒ์ด๋, ์๋๋ฉด ์ compose foundation์ ์ด๋ฏธ ํฌํจํ๊ณ ์๋ ๋ค๋ฅธ library๋ฅผ ์ถ๊ฐํ ๊ฒ์ด๋ ์๋ค. LazyColumn์ ์ฐพ์ ์ ์๋ ํ๋ก์ ํธ์์๋ compose foundation์ด compose material๋ก ์ ๊ทผํ ์ ์๋ ๊ฑฐ์๋ค.
compose foundation๋ง ์ถ๊ฐํ๋ ๊ฒ๋ณด๋ค compose material์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ฅ๊ธฐ์ ์ผ๋ก ๋ณผ ๋ ๋ ์ฝ์งํ ๊ฒ ๊ฐ์์ compose material์ ์ถ๊ฐํ๊ธฐ๋ก ํ๋ค. compose material ํ๋๋ฉด ๋ค๋ฅธ androidx ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ dependency ์ถ๊ฐ๊ฐ ์ค์ด๋ค์ง ์์๊น ์ถ์๋ค.
XML ๋ง์ด๊ทธ๋ ์ด์ ์งํ
https://developer.android.com/codelabs/jetpack-compose-migration?hl=ko#4
๊ธฐ์กด xml ์ฝ๋์ RecyclerView ์์ ฏ์ ์ญ์ ํ๊ณ ๊ทธ ์๋ฆฌ์ ComposeView ์์ ฏ์ ๋ฃ์๋ค.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
...
<androidx.compose.ui.platform.ComposeView
android:id="@+id/composeView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />-->
</LinearLayout>
</layout>
ViewModel ๋ง์ด๊ทธ๋ ์ด์ ์งํ
๊ธฐ์กด์ ์ฐ๋ ExpandedRecyclerView๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ณํํ๋ ์์ ์ ๋นผ๋ ๊ฒ ์ธ์๋ ํ ๊ฒ ๊ฑฐ์ ์์๋ค.
๊ธฐ์กด์ livedata๋ฅผ ๊ทธ๋๋ก ๊ฐ์ ธ๋ค ์ฐ๋ฉด ๋ ์ ๋๋ผ์ ํธํ๋ค.
Activity ๋ง์ด๊ทธ๋ ์ด์ ์งํ
๊ธฐ์กด์ ์ฐ๋ ExpandedRecyclerView์ ๊ด๋ จ๋ ์ฝ๋๋ค์ ๋ค ์ฃผ์์ฒ๋ฆฌํ๋ค.
์ฌ๊ธฐ์ ์ฝ์ง/๊ณ ๋ฏผ ํฌ์ธํธ๋ค์ด ๋ช ๊ฐ์ง ์์๋ค.
์ฝ์ง ํฌ์ธํธ4
์ด ํ์ฌ์ ๋์์ธ ๊ฐ์ด๋๋ ํ ์คํธ ํฌ๊ธฐ๋ฅผ sp๊ฐ ์๋๋ผ dp ๋จ์๋ก ์ง์ ํ๋ค. ํ ์คํธ๋ฅผ sp ๋์ dp๋ก ์ง์ ํ๋ฉด ์ฌ์ฉ์๊ฐ ๋์คํ๋ ์ด ์ค์ ์ผ๋ก ํ๋ฉด ๋ฐ ๊ธ์ ํฌ๊ธฐ ์ค์ ์ ๋ณ๊ฒฝํด๋ ํ ์คํธ์ ํฌ๊ธฐ๋ ๋ณ๊ฒฝ๋์ง ์๋๋ค. ์ฌ์ค ์ฌ์ฉ์๋ฅผ ๊ณ ๋ คํ๋ค๋ฉด ๋ถ์น์ ํ๊ฑฐ๊ณ , ๋์์ธ์ ๊ณ ๋ คํ๋ค๋ฉด ์ฌ์ฉ์ ์ค์ ์ ์ํด ๋์์ธ์ด ๊นจ์ง๋ ์ํฉ์ ์๋ค.
Composable๋ค์ fontSize๋ dp๋ก ์ง์ ํ๋ ๊ธฐ๋ณธ ๊ธฐ๋ฅ ์์ฒด๊ฐ ์์๋ค.
Text
TextUnit
https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/TextUnit
TextUnit์ ์ค์ง sp์ em๋ง ๋ค๋ฃฌ๋ค.
TextUnitType์ sp์ em๋ง ์กด์ฌํ๋ค.
https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/TextUnitType
StackOverFlow์์ ๋ฐฉ๋ฒ์ ์ฐพ์๋ค.
https://stackoverflow.com/a/68603541
extension ํจ์๋ก ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ Int ๊ฐ์ dp > sp ๋ก ๋ณํํด์ฃผ๋ฉด ๋๋ ๊ฒ์ด์๋ค.
์ฝ์ง ํฌ์ธํธ5
Compose๊ฐ ์๊ธฐ๋ฉ๋๋ก ์์ด์ฝ ์์ ๋ฐ๊ฟ๋ฒ๋ ธ๋ค. ์๋ ๋ฆฌ์์ค ์์ ํ์์ธ๋ฐ ์ค์ ๋ก๋ ๊ฒ์ ์์ผ๋ก ๋ ธ์ถ๋๋ค.
StackOverFlow์์ ์ด๊ฒ์ ๋ง๋ ๋ฐฉ๋ฒ์ ์ฐพ์๋ค.
https://stackoverflow.com/a/68238805
tint ๊ฐ์ Color.Unspecified๋ก ์ค์ ํ๋ฉด ๋๋ค.
์ฝ์ง ํฌ์ธํธ6์ด๋ผ๊ณ ์ผ์ง๋ง ์ฌ์ค ์ ๋ง ํธํ๊ฒ ๋ง๋ ๊ฒ
๋ผ์ธ ํ ์ค ๊ทธ๋ ค๋ฃ์ด์ผ ํ๋๋ฐ ๋ญ ์๋ ์ถ์๋ค.
Divider๋ผ๋ Composable์ด ์์๋ค.
์ฝ์ง ํฌ์ธํธ7๋ผ๊ณ ๋ถ๋ฅด๊ธฐ์๋ ๋ด๊ฐ ๊ธฐ๋ณธ๊ธฐ๊ฐ ๋ถ์กฑํ๋ค.
๋ง๋ค๋ ค๊ณ ํ Expanded List์ ์์ดํ ์ ๊ธฐ๋ณธ ํค๋๊ฐ ์๊ณ , ํค๋๋ฅผ ํด๋ฆญํ๋ฉด ๊ทธ ์๋๋ก ์ฝํ ์ธ ๊ฐ ๋ด๊ธด ๋ทฐ๊ฐ ๋ ธ์ถ๋๊ฑฐ๋ ์ฌ๋ผ์ง๋ ๊ฒ์ด์๋ค. ํค๋๋ฅผ Text๋ก ๋ง๋ค๊ณ , padding ๊ฐ๊ณผ clickable ๊ฐ์ ์ค์ ํ๋ค. ์ด๋ ๊ฒ ํ๊ณ ๋์ ๋ณด๋ ํด๋ฆญ ์์ญ์ด ๋ด๊ฐ ์๊ฐํ๋ ์์ญ๊ณผ๋ ๋ฌ๋๋ค. ๋๋ padding๋ ์์ญ๊น์ง๋ Text composable์ ์์ญ์ผ๋ก ๋ณด์ด๋๊น ๋ค ํด๋ฆญ์ด ๋๋ ์ค ์์๋๋ฐ, padding๋ ์์ญ์ ์ ์ธํ๊ณ ํ ์คํธ๊ฐ ๋ณด์ด๋ ๊ทธ ์์ญ๋ง ํด๋ฆญ์ด ๊ฐ๋ฅํ๋ค. Text composable์ ๋ค๋ฅธ wrapper composable๋ก ๊ฐ์ธ๊ณ , ๊ทธ wrapper composable์ clickable ๊ฐ์ ์ค์ ํ๋ค. ์ด์ ์ผ ๋ด๊ฐ ์ํ๋ Text ์์ญ ์ ๋ถ์ ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ๋จนํ๋ค.
* ์ถ๊ฐ : ๊ธ์ ๋ค ์ฐ๊ณ ๋์ ๋์ค์ ์์๋ค. Modifier๋ฅผ ์ธ ๋ ํจ์์ ์์๊ฐ ์ค์ํ ๊ฑฐ์๋ค. padding()์ ๋ค๋ฅธ ํจ์์ ๊ฐ์ด ์ฐ๋ ์์์ ๋ฐ๋ผ์ ๊ธฐ์กด ๋ทฐ์์ ์ฐ๋ margin์ด๋ padding ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์๋ค. ์๋ง ๋ด๊ฐ Text์ Modifier๋ฅผ ์ค์ ํ์ ๋, padding()์ ์ฐ๊ณ ๊ทธ ์๋์ clickable()์ ์ผ์๋๋ณด๋ค. ์ฝ์ง์ด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ์๋ ๋ถ๋๋ฌ์ด ๊ธฐ๋ณธ๊ธฐ ๋ถ์กฑ๐ ๋ ์ด์์ ๊ณต๋ถํ๋ฌ ๊ฐ์ผ๊ฒ ๋ค.
์ฝ์ง ํฌ์ธํธ8
ํด๋ฆญ ์ด๋ฒคํธ์ ๋ฆฌํ ํจ๊ณผ๊ฐ ๋ณด๊ธฐ ์ซ์๋ค. ์ด๊ฒ์ ์ ๊ฑฐํ๊ณ ์ถ์๋ค.
Compose๋ก ๋ง๋ Expanded List ์์ ๋ค์ ๋ณด๋ค๊ฐ ๋ฐฉ๋ฒ์ ์์๋ค. ์ฐธ๊ณ ํ ๊ธ์ด๋ค.
https://johncodeos.com/how-to-make-expandable-list-with-jetpack-compose/
clickable ์ค์ ์ ๋ค์๊ณผ ๊ฐ์ด ํ๋ฉด ๋๋ค.
modifier = Modifier
.clickable(
indication = null,
interactionSource = remember {
MutableInteractionSource()
},
onClick = { /** ์์ฑ **/ })
์ฝ์ง ํฌ์ธํธ9๊ฐ ๋ ๋ปํ ๊ฒ
์์ดํ ์ด ํ์ฅํ๊ฑฐ๋ ์ถ์๋ ๋ ์ ๋๋ฉ์ด์ ์ด ๋ค์ด๊ฐ๊ธธ ์ํ๋ค. ์์ฒญ๋ ์ ๋๋ฉ์ด์ ์ ์ํ ๊ฒ์ด ์๋๋ผ์, ๊ฐ๋จํ๊ฒ ๊ตฌํํ๊ณ ์ถ์๋ค.
Modifier์ animateContentSize()๋ผ๋ ๊ธฐ๋ฅ์ด ์๋ ๊ฒ์ ์ฐพ์๋ค. ์ด๊ฒ์ผ๋ก ๊ฐ๋จํ๊ฒ ์ ๋๋ฉ์ด์ ์ ๋ฃ์๋ค.
์ฝ์ง ํฌ์ธํธ10
์ํ ๊ด๋ฆฌ๋ฅผ ์ด๋ป๊ฒ ํ ๊ฒ์ธ๊ฐ๋ฅผ ๊ณ ๋ฏผํ๋ค. ์์ดํ composable์ stateful ํ๊ฒ ๋ง๋ค ๊ฒ์ธ๊ฐ, statelessํ๊ฒ ๋ง๋ค ๊ฒ์ธ๊ฐ ํ๋ ๊ณ ๋ฏผ์ด์๋ค.
๋ฌธ์์ ๋ฐ๋ฅด๋ฉด
Stateful Composable
- ํธ์ถ์๊ฐ ์ํ๋ฅผ ์ ์ดํ ํ์๊ฐ ์์ ๋ ํธํ๋ค.
- ์ฌ์ฌ์ฉํ๊ธฐ ์ด๋ ต๋ค.
- ํ ์คํธํ๊ธฐ ์ด๋ ต๋ค.
Stateless Composable
- ํธ์ถ์๊ฐ ์ํ๋ฅผ ์ ์ดํ ํ์๊ฐ ์์ ๋ ์ ์ฉํ๋ค.
- ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
- ํ ์คํธ๊ฐ ์ฉ์ดํ๋ค.
Stateful, Stateless์ ๋ํด ๋ฌด์์ด ๋ ์ข๊ณ ๋์๊ณ ๋ฅผ ์ด์ผ๊ธฐํ์ง ์์๋ค.
๋ง๋ค๊ณ ์ ํ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉ์์๊ฒ ๋ ธ์ถ๋ ์ผ์ด ์ฆ์ง๋ ์๊ณ , ์์ดํ ์ด ์ด๋ฆฌ๊ณ ๋ซํ๊ณ ์ํ๋ฅผ ๋ทฐ๋ชจ๋ธ์๊น์ง ์ ์ฅํด์ผํ ์ ๋๋ก ์ค์ํ์ง๋ ์๋ค.
Statefulํ๊ฒ ๋ง๋ค๊ธฐ๋ก ํ๋ค.
class AgreementActivity : BaseActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
...
with(binding.coposeView) {
setContent {
val list by viewModel.list.observeAsState()
list?.let { ExpandealbeList(it) }
}
}
}
}
@Composable
fun ExpandableList(list: List<Agreement>) {
LazyColumn {
items(list) { agreement ->
ExpandableItem(title = agreement.name, content = agreement.content)
}
}
}
@Composable
fun ExpandableItem(title : String, content: String) {
Column(
modifier = Modifier
.fillMaxWidth()
.animateContentSize()
) {
var isExpanded by remember {
mutableStateOf(false)
}
Row(
modifier = Modifier
.fillMaxWidth()
.height(49.dp)
.background(color = Color.White)
.cilckable(
indication = null,
interactionSource = remember {
MutableInteractionSource()
},
onClick = { isExpanded = != isExpanded })
) {
Text(
text = title,
color = colorResource(id = R.color.title),
fontSize = 15.textDp,
modifier = Modifier
.padding(all = 16.dp)
.weight(1f)
)
Icon(
painter = painterResource(id = if (isExpanded) R.drawable.arrow_close else R.drwable.arrow_open),
contentDescription = null,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(10.dp),
tint = Color.Unspecified
)
}
Divider(color = colorResource(id = R.color.divider), thickness = 1.dp)
if (isExpanded) {
Text(
text = content,
modifier = Modifier
.fillMaxWidth()
.background(color = colorResource(id = R.color.content_background)
.padding(all = 16.dp),
color = colorResource(id = R.color.content),
fontSize = 12.textDp
)
}
}
}
fun Int.textDp(density: Density) : TextUnit = with(density) {
this@textDp.dp.toSp()
}
val Int.textDp: TextUnit
@Composable get() = this.textDp(density = LocalDensity.current)
Stateless ๋ฒ์ ๋ ๋ง๋ค์ด ๋ณด๊ธฐ๋ ํ๋ค. Agreement ๊ฐ์ฒด์ isExpanded ๊ฐ์ด ์๋ค๋ฉด ์ด๋ ๊ฒ ์ฝ๊ฒ ์์ ํ ์ ์๋ค.
@Composable
fun ExpandableList(list: List<Agreement>) {
LazyColumn {
val expandedStatusList = list.map { it.isExpanded }
itemsIndexed(list) { index, item ->
var isExpanded by remember {
mutableStateOf(statusList[index])
}
ExpandableItem(
title = item.name,
content = item.content,
isExpanded = isExpanded,
onClick = { isExpanded = !isExpanded }
)
}
}
}
@Composable
fun ExpandableItem(title: String, content: String, isExpanded: Boolean, onClick: () -> Unit) {
Column(
modifier = Modifier
.fillMaxWidth()
.animateContentSize()
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(49.dp)
.background(color = Color.White)
.cilckable(
indication = null,
interactionSource = remember {
MutableInteractionSource()
},
onClick = onClick)
) {
...
// ์์ ์ฝ๋์ ๋์ผ
}
...
// ์์ ์ฝ๋์ ๋์ผ
}
}
์ฝ์ง ํฌ์ธํธ8์์ ์ฐธ์กฐํ ๋ธ๋ก๊ทธ์์์ ๋ฐฉ์์ผ๋ก ๋ง๋ค๋ฉด, ์์ดํ Composable์ด ๋ชจ๋ recomposition ๋๋ค. Compose์ ์ฅ์ ์ด ์ ๋ฐ์ดํธ๊ฐ ํ์ํ Compose๋ง recomposeํ๋ค๋ ๊ฒ์ธ๋ฐ, ํ ์คํธ๋ฅผ ํด๋ณด๋ ์ด ์ฅ์ ์ ์ด๋ฆด ์ ์๋ ๊ตฌํ์ด๋ผ๋ ์๊ฐ์ ํ๊ฒ ๋๋ค.
๋ด๊ฐ ์์ฑํ Stateless ๋ฒ์ ์์๋, ์์ดํ Composable์ isExpanded ์ํ๋ฅผ ๊ฐ๋ณ๋ก ์ ์ฅํ๋ค. ๊ทธ๋์ Composable ๊ฐ๋ณ๋ก ์ํ๋ฅผ ๊ฐ๊ณ , ๋ณ๊ฒฝ๋ ์ํ๋ฅผ ๊ฐ๋ Composable๋ง recompose๋๋ค. ๋ธ๋ก๊ทธ ์์ ์ฝ๋์์๋ isExpanded ๊ฐ์ ๋ฆฌ์คํธ ์์ฒด๋ฅผ ์ํ๋ก ์ ์ฅํ๋ค. ์์ดํ ์ ํด๋ฆญํ๋ฉด ๋ฆฌ์คํธ ์ ๋ณด๊ฐ ์ ๋ฐ์ดํธ๋๊ณ , ๊ทธ๋ ๊ฒ ์ํ(๋ฆฌ์คํธ ์ํ ์ ๋ณด)์ ์ฐ๊ฒฐ๋ ๋ชจ๋ ์์ดํ ๋ค์ด recompose๋๋ค. ์ด๊ฑด ๋ด๊ฐ ์ํ๋ ๊ทธ๋ฆผ์ด ์๋์๋ค.
์ฝ์ง ํฌ์ธํธ11
๊ธฐ์กด ๋ฆฌ์ฌ์ดํด๋ฌ๋ทฐ์๋ android:overScrollMode="never" ์ค์ ์ด ๋์ด ์๋ ๊ฒ์ ํ์ธํ๋ค.
https://stackoverflow.com/a/69478797
LazyColumn์ wrapper๋ก CompositionLocalProvider๋ฅผ ๊ฐ์ธ์คฌ๊ณ , LocalOverscrollConfiguration์ null๋ก ๋ฃ์๋ค. compose foundation ๋ฒ์ 1.2.0์ ์ฐ๊ณ ์์ด์ @OptIn(ExperimentalFoundationApi::class) ์ด๋ ธํ ์ด์ ์ ๋ฃ์ด์ค์ผ ํ๋ค.
๊ฒฐ๊ณผ
๊ธฐ์กด ExpandedRecyclerView ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๊ฑฐ์ ์ฑ๊ณตํ๋ค.
ํ์คํ ์ ๋๋ฉ์ด์ ์ ๋ฃ๋ ๊ฒ์ด ํธํ๊ณ , RecyclerView๋ก ๋ง๋๋ ๊ฒ์ ๋นํด ์ฝ๋๋ฅผ ๋ ์ผ๋ค.
'๊ณณ๊ฐ์์ ์ธ์ฌ๋๋ค > ์ค๋ฌด' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android][DataStore] DataStore ๋๊ธฐ์ ์ผ๋ก ์ฐ๊ธฐ (0) | 2023.10.08 |
---|---|
[Android]์ฑ ๋น๋ ์ค์ - zero base ํ๋ก์ ํธ ๊ฐ๋ฐ ์ ๋ด์ฉ ์ ๋ฆฌ์ ํ์์ฑ์ ๋๋ ๊ฒ๋ค (0) | 2023.10.03 |
[Kotlin] Calendar extensions (0) | 2023.01.12 |
[Android][Kotlin] ์ฌ์ฉ์๊ฐ ์ ํํ ํญ์ ๋ฌธ๊ตฌ์ ๋ณผ๋ ์ฒ๋ฆฌ (0) | 2023.01.12 |
[Kotlin] BaseUseCase (0) | 2023.01.12 |