Android Jetpack Compose 사용 시 알아야 할 state 상태와 기본 레이아웃‼️
🚨 State - 앱의 상태
Android Compose 는 현재 상태에 따라 Composable 를 구성하여 사용자에게 보여질 화면을 구성한다.
만약 상태(state) 가 변화게 되면 재구성(Re-Compose) 를 통해 화면을 업데이트한다.
Composable 은 상태를 가지는 여부에 따라 두가지 타입으로 나뉜다.
✔️ 상태를 가지고 있는 Stateful Composable
✔️ 상태를 가자지 않는 Stateless Composable
- Stateful Composable 은 state 가 바뀌면 자기 자신과 자식의 Composable 을 재구성(ReComposition) 하게 된다.
- Stateless Composable 은 상태가 없기 때문에 스스로 재구성을 할수 없으며 부모의 Composable 이 재구성되어야 자신을 재구성을 할 수 있게 된다.
이전 state 를 기억해야 하는 경우 remember 를 이용해 값을 저장할 수 있다
state 저장 및 변경 시 MutableState 객체를 사용하며 MutableState 생성을 위해 mutableStateOf api 가 사용된다.
MutableState 객체 선언 방법
- val mutableState = remember { mutableStateOf(default) }
- var value by remember { mutableStateOf(default) }
- val (value, setValue) = remember { mutableStateOf(default) }
setContent {
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
) {
// *** 1. val mutableState = remember { mutableStateOf(default) }
val txtState1 = remember {mutableStateOf("")}
TextField(
value = txtState1.value,
onValueChange = { txtValue -> txtState1.value = txtValue }
)
// *** 2. var value by remember { mutableStateOf(default) }
var txtState2 by remember {mutableStateOf("")}
TextField(
value = txtState2,
onValueChange = { txtValue -> txtState2 = txtValue }
)
// *** 3. val (value, setValue) = remember { mutableStateOf(default) }
val (txtState3, setTxtState) = remember {mutableStateOf("")}
TextField(
value = txtState3,
onValueChange = setTxtState
)
}
}
State remeber 를 사용한 TextField
https://developer.android.com/jetpack/compose/state?hl=ko
🚨 State + 기본 레이아웃 사용하기(Box, Card, Image, IconButton, Icon)
기본 레이아웃 사용하기
✔️ Box 레이아웃
- FrameLayout 과 비슷
- 레이아웃을 겹쳐서 사용 가능
- fillMaxWeight : 가로길이가 꽉차게
- fillMaxHeight : 세로길이가 꽉차게
- fillMaxSize : 가로세로 다 꽉차게
- align : Box 내부 Child 위치를 지정 (Alignment.TopStart, Alignment.TopCenter, Alignment.BottomEnd, ...)
✔️ Card 레이아웃
- CardView 와 비슷
- roundShape(모서리 둥글게), elevation(그림자) 설정 가능
✔️ Image 레이아웃
- ImageView 와 비슷
- 이미지 리소스, scale 설정 가능
✔️ IconButton 레이아웃
- onClick 이벤트 설정 가능
✔️ Icon 레이아웃
- 이미지 리소스, tint 설정 가능
✍🏻 state 상태와 기본 레이아웃들을 사용하여
곰돌이 이미지와 하트 아이콘을 Box 로 겹쳐서 위치하도록 하고,
비어있는 하트 아이콘을 클릭하면 하트색상 활성화되게 (♡ → ♥︎),
색상이 있는 하트 아이콘을 클릭하면 비어있는 하트로 되도록 (♥︎ → ♡)
구현하였습니다.
결과 화면
♡ → ♥︎ & ♥︎ → ♡
Activity 소스코드 (BasicLayoutActivity.kt)
class BasicLayoutActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var isFavCard by rememberSaveable { // isFavCard 는 Boolean 값이다 remeberSaveable : 화면 회전시에도 상태 저장
mutableStateOf(false)
}
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
) {
CardFavorite( // ImageCard 함수 사용
mCardModifier = Modifier
.height(250.dp)
.fillMaxWidth(0.7f)
.padding(10.dp)
.align(Alignment.Center), //Box 내부 Child 위치를 지정 - Center
mBoxModifier = Modifier
.background(colorResource(id = R.color.teal_200))
.padding(10.dp),
mPainter = painterResource(id = R.drawable.img_mint),
mIsFavCard = isFavCard
) { paramFavCard ->
isFavCard = paramFavCard
}
}
}
}
}
/**
* ImageCard 컴포저블 함수
*
* @param mCardModifier Card 레이아웃의 modifier
* @param mBoxModifier Box 레이아웃의 modifier
* @param mPainter Image 레이아웃의 painter
* @param mIsFavCard IconButton 레이아웃의 색상 활성화 여부
* @param onTabFavCard IconButton 레이아웃의 onClick 콜백
*/
@Composable
fun CardFavorite(
mCardModifier: Modifier,
mBoxModifier: Modifier,
mPainter: Painter,
mIsFavCard: Boolean,
onTabFavCard: (Boolean) -> Unit
) {
/**
* Card 레이아웃
* - CareView 와 비슷
*/
Card(
modifier = mCardModifier,
shape = RoundedCornerShape(8.dp),
elevation = 5.dp,
) {
/**
* Box 레이아웃
* - FrameLayout 과 비슷
* - 레이아웃을 겹쳐서 사용 가능
*/
Box(
modifier = mBoxModifier,
) {
/**
* Image 레이아웃
*/
Image(
painter = mPainter,
contentDescription = "poster",
contentScale = ContentScale.Crop
)
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.TopEnd
) {
/**
* IconButton 레이아웃
*/
IconButton(onClick = {
onTabFavCard(!mIsFavCard)
}
) {
/**
* Icon 레이아웃
*/
Icon(
imageVector = if(mIsFavCard) Icons.Default.Favorite else Icons.Default.FavoriteBorder,
contentDescription = "favorite card btn",
tint = Color.Red
)
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun BasicLayoutPreview() {
var isFavCard = true
Box(
modifier = Modifier
.fillMaxWidth() // 가로길이 꽉차게
.fillMaxHeight() // 세로길이 꽉차게
.fillMaxSize(), // 가로세로 꽉차게
) {
CardFavorite( // ImageCard 함수 사용
mCardModifier = Modifier
.height(250.dp)
.fillMaxWidth(0.7f)
.padding(10.dp)
.align(Alignment.Center), //Box 내부 Child 위치를 지정 - Center
mBoxModifier = Modifier
.background(colorResource(id = R.color.teal_200))
.padding(10.dp),
mPainter = painterResource(id = R.drawable.img_mint),
mIsFavCard = isFavCard
) { paramFavCard ->
isFavCard = paramFavCard
}
}
}
감사합니다 :)
'📱 안드로이드 Android ~ Kotlin' 카테고리의 다른 글
[Android/Google] 안드로이드 앱에 구글 광고 AdMob(애드몹) 적용하기 (0) | 2024.05.02 |
---|---|
[안드로이드/Android] Jetpack Compose (0) | 2023.06.19 |
[Android/Kotlin] Google Maps API 사용해서 지도 표시하기 (2) | 2023.01.10 |
[Android/Kotlin] ViewPager2 를 이용한 스크롤 시 애니메이션 적용(smoothScroll, PageTransformer) (0) | 2022.11.03 |
[Android/Kotlin] ViewPager2 를 이용한 무한 스크롤(Infinite Scroll)/자동 스크롤(Auto Scroll) (0) | 2022.10.31 |