์ด๋ฒ ํฌ์คํ ์์๋ compose UI ๊ณต๋ถํ๋ ๋ด์ฉ์ ๋์ ์ฌ๋ณด๊ฒ ๋ค.
์ด์ ํฌ์คํ
https://rkdrkd-history.tistory.com/44
์ด๋ฒ์ ์ ๋ฆฌํ ๋ด์ฉ์ compose์์ glide ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๋ง๋ค์ด๋ณผ ์์ ๋ lazyColumn(recyclerView)๋ฅผ ์ด์ฉํด ํ๋กํ ์ฌ์ง๊ณผ ์ ์ ์ด๋ฆ, ์ค๋ช ์ ๋ฃ์ด๋ณผ ๊ฒ์ด๋ค
๋จผ์ ์์ฑํ๋ฉด๋ถํฐ ๋ณด๋๋ก ํ์
์ ๊ฒ(?)์ ๋ง๋ค๊ธฐ ์ํด ๋จผ์ ํด์ผ ํ ๊ฒ์
AppBar ๋ง๋ค๊ธฐ!๊ฐ ์๋๊ณ lazy column(recyclerView)์ ๋ค์ด๊ฐ ์์ดํ
(card)๋ฅผ ๋ง๋ค์ด์ฃผ๋๋ก ํ์.
1. item(card) ๋ง๋ค๊ธฐ
@Composable
fun RecyclerItem(randomUser: RandomUser) {
val typography = MaterialTheme.typography
Card(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp),
elevation = 10.dp,
shape = RoundedCornerShape(12.dp)
) {
Row(
modifier = Modifier
.padding(10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(10.dp)
) {
ProfileImage(source = randomUser.profileImage) // ํ๋กํ ์ด๋ฏธ์ง๋ฅผ ์ค์ ํ๋ค.
Column() {
Text(text = randomUser.name, style = typography.subtitle1)
Text(text = randomUser.description, style = typography.body1)
}
}
}
}
ํ๋ํ๋(?) ์ค๋ช ํด ์ฃผ๊ฒ ๋ค
- elevation: Card ํ ๋๋ฆฌ์ ๊ทธ๋ฆผ์(?)ํจ๊ณผ๋ฅผ ์ค๋ค(ํ ๋๋ฆฌ๊ฐ ์ ๋ช ํ ๋ณด์ฌ์).
- shape: Card์ ๋ชจ์์ ๋ํ๋ธ๋ค
์) RoundedCornerShape(ํ ๋๋ฆฌ๋ฅผ ๋ฅ๊ธ๊ฒ), CircleShape(์ํ) - verticalAlignment: Row์ ํ์ ๋ทฐ๋ค์ ์์ง ์ ๋ ฌํ๋ค
- horizontalArrangement: ์์ดํ ๊ฐ์ ์ํ ๋๋น๋ฅผ ๋ํ๋ธ๋ค.
2. ํ๋กํ ์ด๋ฏธ์ง ์ค์ ํ๊ธฐ
@Composable
fun ProfileImage(source: String, modifier: Modifier = Modifier) {
// image bitmap
val bitmap: MutableState<Bitmap?> = remember { mutableStateOf(null) }
val imageModifier: Modifier = modifier
.size(50.dp, 50.dp)
.clip(CircleShape)
Glide.with(LocalContext.current)
.asBitmap()
.load(source)
.into(object : CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
bitmap.value = resource
}
override fun onLoadCleared(placeholder: Drawable?) {}
})
// bitmap ์ด ์์ผ๋ฉด
bitmap.value?.asImageBitmap()?.let { fetchedBitmap ->
Image(
bitmap = fetchedBitmap,
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = imageModifier
)
} ?: Image(
painter = painterResource(id = R.drawable.ic_empty_user),
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = imageModifier
)
}
์ด๋ฒ์๋ ํ๋ํ๋(?) ์ค๋ช ํ์๋ฉด
- clip: ์ด๋ฏธ์ง์ ๋ชจ์์ ์ก์์ค๋ค(RoundedCornerShape, CircleShape)
- onResourceReady: ์ด๋ฏธ์ง๊ฐ ์ค๋น๋์์๋ ํธ์ถ๋๋ ๋ฉ์๋
// bitmap ์ด ์์ผ๋ฉด
bitmap.value?.asImageBitmap()?.let { fetchedBitmap ->
Image(
bitmap = fetchedBitmap,
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = imageModifier
)
} ?: Image(
painter = painterResource(id = R.drawable.ic_empty_user),
contentDescription = null,
contentScale = ContentScale.Fit,
modifier = imageModifier
)
์ด ๋ถ๋ถ์ ๋นํธ๋งต์ผ๋ก ์ฑ๊ณต์ ์ผ๋ก ๋ณํ๋์์๋ ์์ ์ฝ๋๊ฐ ์ํ๋๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ ์ฝ๋๊ฐ ์ํ๋๋ค.
3. toolbar
๋ง์ง๋ง์ผ๋ก toolbar๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ ์์๋ณด์.
@Composable
fun MyApPBar() {
TopAppBar(
elevation = 10.dp,
backgroundColor = MaterialTheme.colors.primary,
modifier = Modifier.height(58.dp)
) {
Text(
text = "๋ฆฌ์คํธ",
modifier = Modifier
.padding(8.dp)
.align(Alignment.CenterVertically),
fontSize = 18.sp,
fontWeight = FontWeight.Black
)
}
}
topAppBar์์ Text๋ฅผ ๋ฃ์ด์ AppBar์ title์ ์ค์ ํ ์ ์๋ค.
์ ๋ฆฌ
์ด๋ฒ์ ๊ณต๋ถํด๋ณด๋ฉด์ compose์ glide๋ฅผ ์ฒ์ ์ฌ์ฉํด๋ดค๋ค.
์ด๋ฒ ๊ณต๋ถ๋ก compose์ ์ฅ์ ์ ๋ ์ฝ๊ฒ ์๊ฒ ๋์๋ค(์๋๋ ๋ฅ๊ทผ ์ด๋ฏธ์ง ์ฐ๋ ค๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐํด์ ์จ์ผ ํ์ง๋ง, ์๊ทธ๋๋ ๋๋ค๋๊ฒ์ด ์ข์๋ค.๊ฐ๊ฟ)
'๐ฑ| Android > ๐ | Jetpack' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android, Kotlin] Compose UI ์ ๋ฆฌ(6) (0) | 2023.04.07 |
---|---|
[Android, Kotlin] Android Activity์ lifeCycle ์ ๋ฆฌ (0) | 2023.03.17 |
[Android, Kotlin] Compose UI ์ ๋ฆฌ(4) (0) | 2022.12.05 |
[Android, Kotlin] Compose UI ์ ๋ฆฌ(3) (0) | 2022.12.04 |
[Android, Kotlin] Compose UI ์ ๋ฆฌ(2) (0) | 2022.12.03 |