Compose 전 글에서 포스팅 했던 내용중에 Box태그가 있었다.
이번 글에서는 위와 같은 뷰를 카드 뷰 안에 Box태그를 두개 넣어 image와 하트 아이콘을 넣어보자!
setContent {
var isFavorite by rememberSaveable{ //remember가 기억을 해주는 형태
mutableStateOf(false)
}
//이미지 카드를 여러 개 사용하고, 재사용할 수 있음
ImageCard(
modifier = Modifier
.fillMaxWidth(0.5f)
.padding(16.dp),
isFavorite = isFavorite
){ favorite ->
isFavorite = favorite //값을 갱신함
}
}
@Composable
fun ImageCard(
modifier: Modifier = Modifier, //기본값으로 지정
isFavorite : Boolean, //상수임 변수가 아니라
onTabFavorite : (Boolean) -> Unit //콜백으로 만들수있음
){
// var isFavorite : Boolean //이렇게 할 수 있었음
//state를 활용할 수 있음 , Compose에서는
// var isFavorite by rememberSaveable{ //remember가 기억을 해주는 형태
// mutableStateOf(false)
// } //mutableState 형식
//by를 사용해서 mutablestate 속성에서 -> boolean형식으로 바뀜
Card(
modifier = modifier,
// .fillMaxWidth(0.5f)
// .padding(16.dp),//절반을 의미함
shape = RoundedCornerShape(8.dp),
elevation = 5.dp,
){
Box(
modifier = Modifier.height(200.dp)
){
Image(painter = painterResource(id = R.drawable.servicelogo), //이미지 id
contentDescription = "logo", //이미지 설명
contentScale = ContentScale.Crop, //이미지가 좀 예쁘게
)
Box(
modifier = Modifier.fillMaxSize(), //크기를 꽉 채움
contentAlignment = Alignment.TopEnd //오른쪽 맨위
){
IconButton(onClick = {
//isFavorite = !isFavorite //value를 써주는 불편함이 있음 by를 적어주어야함. 생략하기 위해
onTabFavorite(!isFavorite)
}){
Icon(imageVector = if(isFavorite) Icons.Default.Favorite else Icons.Default.FavoriteBorder,
contentDescription = "like",
tint = Color.White,
)
}
}
}
}
ImageCard를 생성하는 Composable함수와 함수를 불러내는 setContent이다.
먼저 ImageCard에 생성자가 없다고 가정해보자.
그럼, Card( )안에 modifier를 통해 Card의 크기 및 해당 특징들을 적어주어야하고, ImageCard안에 하트를 눌렀는지, 안눌렀는지 해당하는 변수도 위의 주석코드와 같이 적어주어야한다.
만일 ImageCard안에 var isFavorite와 같은 변수를 지정해준다면, 다른 이미지카드안에서는 이 함수를 재사용하지 못할 것이다.
Composable은 무엇보다도 재사용하기 위해 만들어 졌는데 이런 변수들이 있으면 있을수록 다른 용도로 재사용하기 어려워질 것이다.
그럼 같은 Image가 담긴 Card뷰여도 거의 비슷한 함수를 하나 더 만들어주어야한다.
따라서 위와 같이 ImageCard안에 생성자를 modifier, isFavorite를 적어주고 setContent에서 불러오는 식으로 구현하였다.
또한, 생성자에 적어준 isFavorite은 상수이기 때문에 밑에서 변경을 할 수 없다.
따라서 위와 같이 onTabFavorite이라는 콜백을 만들어주어 클릭했을 때 콜백하여 함수를 호출하는 부분에서 값을 갱신하였다.
이제 뷰 안에 코드를 살펴보자.
첫 번째 Box태그의 높이를 설정하여 해당 Image의 크기를 지정해주었다.
painter를 통해 해당 이미지를 불러오고, 그 안에 또 다른 Box태그를 만들어주어 하트아이콘을 오른쪽 맨 위에 위치하게 하였다.
해당 아이콘은 클릭할 수 있기 때문에 onclick를 적어주어 아까 설정했던 onTabFavorite를 통해 현재 state의 값을 갱신하였다.
여기서 주의할 점이 있다!
만일 재사용될 일이 없어 ImageCard함수 안에 하트관련한 상태의 변수 isFavorite을 만들고 싶다면,
// var isFavorite by rememberSaveable{ //remember가 기억을 해주는 형태
// mutableStateOf(false)
// } //mutableState 형식
위와 같이 remember가 아닌, rememberSaveable을 사용해야한다!
왜냐하면 Compose도 마찬가지로 액티비티의 생명주기를 따르기 때문이다.
화면을 돌리게 되면 액티비티의 생명주기에 따라 하트의 값이 초기화가 이루어진다.
원래 이 때 우리는 saveInstanceOf나, 뷰모델을 사용하여 이를 방지하였는데, Compose에는 rememberSaveable을 사용하여
값이 초기화되는 문제를 방지할 수 있다!
GitHub - SsongSik/Jetpack_Compose: Creating apps using Jetpack Compose
Creating apps using Jetpack Compose. Contribute to SsongSik/Jetpack_Compose development by creating an account on GitHub.
github.com
'Android > Compose' 카테고리의 다른 글
[Compose] ViewModel, State (1) | 2022.09.23 |
---|---|
[Compose] Navigation (0) | 2022.09.22 |
[Compose] TextField, Scaffold, SnackBar (0) | 2022.09.21 |
[Compose] Box, 리스트, LazyColumn (0) | 2022.09.12 |
[Compose] Jetpack Compose 들어가며 (0) | 2022.09.10 |