card 안에 box 를 넣어주고 그 안에 이미지를 추가하려 한다.
setContent {
ImageCard()
}
@Composable
fun ImageCard(){
Card(
modifier= Modifier
.fillMaxWidth(0.5f) //fraction : 비율
.padding(16.dp),
shape = RoundedCornerShape(8.dp), //모서리 둥글게
elevation = 5.dp
){
Box (
modifier= Modifier.height(100.dp)
){
Image(
painter = painterResource(id = R.drawable.emergency),
contentDescription = "poster", //필수
contentScale = ContentScale.Crop
)
}
}
}
card의 modifer에 있는 .fillMaxWidth(0.5f)는 width를 꽉채워 표시하라는 설정에 비율을 넣어준 것이다.
그래서 width 에서 0.5f 즉, 전체의 절반 비율로 꽉차게 설정한 것이다.
shape = RoundedCornerShape(8.dp) 는 카드의 모서리를 둥글게 설정한 것이고, elevation은 elevation기능이다.
Image를 가져오는 것에 여러 방법이 있지만 그중 drawable 파일을 가져다 쓸 것이기 때문에 Painter를 사용한다.
contentDexriprion은 필수이고, contentScale = ContentScale.Crop를 추가하여 이미지를 크롭하여 크기조정한다.
이 이미지 안에 하트 아이콘을 넣어주려고 한다.
Box (
modifier= Modifier.fillMaxSize(),
contentAlignment = Alignment.TopEnd //오른쪽 위에
){
IconButton(onClick = {}) {
Icon(
imageVector = Icons.Default.FavoriteBorder,
contentDescription ="Favorite",
tint = Color.White
)
}
}
이 코드를 이미지 바로 아래에 넣어 주면 된다.
그래서 상위 Box의 크기에 fillMaxSize하고, Alignment.TopEnd 하여
이렇게 표시가 된다.
그다음은 아이콘을 클릭했을 때 변화가 있게끔 수정해 보자.
//상태 기억 필요
val isFavorite = remember { //var isFavorite: MutableState<Boolean>
mutableStateOf(false)
} //변경되면 ui가 다시 그려짐
이것을 추가하여 상태를 기억할 수 있는 상수를 선언을 해주고,
IconButton(onClick = {
isFavorite.value=!isFavorite.value
}) {
Icon(
imageVector = if(isFavorite.value) Icons.Default.Favorite else Icons.Default.FavoriteBorder,
contentDescription ="Favorite",
tint = Color.White
)
}
이렇게 수정해주면 된다.
onClick에 클릭했을 때 마다 isFavorite의 value가 반대의 값이 들어가도록 해주고
imageVector를 넣어줄 때 상태를 기억하고 있는 상수 isFavorite가 true일때와 false일때 아이콘의 종류를 달리 할 수 있도록 해주면 된다.
그리고 매번 값을 가져올 때 .value를 써주는 것이 번거로우니
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
이걸 import 해주고
var isFavorite by remember { //var isFavorite: Boolean
mutableStateOf(false)
}
=를 by로 수정하면 된다.
그리고 변수의 형태가 MutableState<Boolean> 가 아닌 Boolean로 변하였기 때문에 val 이 아닌 var 로 선언해 주어야 한다.
상태보존을 위해서 remeber 대신 rememberSaveable를 사용하면 핸드폰을 기울일 때 상태가 보존이 된다고 하는데,
remember로 사용해도 상태가 유지가 되니 이 부분을 좀 더 알아볼 필요가 있다.
지금까지의 코드는 아래와 같다.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ImageCard()
}
}
}
@Composable
fun ImageCard(){
//상태 기억 필요
var isFavorite by rememberSaveable { //var isFavorite: MutableState<Boolean>
mutableStateOf(false)
} //변경되면 ui가 다시 그려짐
Card(
modifier= Modifier
.fillMaxWidth(0.5f) //fraction : 비율
.padding(16.dp),
shape = RoundedCornerShape(8.dp), //모서리 둥글게
elevation = 5.dp
){
Box (
modifier= Modifier.height(100.dp)
){
Image(
painter = painterResource(id = R.drawable.emergency),
contentDescription = "poster", //필수
contentScale = ContentScale.Crop
)
Box (
modifier= Modifier.fillMaxSize(),
contentAlignment = Alignment.TopEnd //오른쪽 위에
){
IconButton(onClick = {
isFavorite=!isFavorite
}) {
Icon(
imageVector = if(isFavorite) Icons.Default.Favorite else Icons.Default.FavoriteBorder,
contentDescription ="Favorite",
tint = Color.White
)
}
}
}
}
}
그런데 이렇게 하면 ImageCard()가 값을 유지하고 있기 때문에 재사용될 수 없다.
그래서 밖에서 값을 주는 방법으로 수정을 해야한다.
그리고 상태 뿐만 아니라 modifier로 외부에서 지정해 주면 좋다.
setContent {
var isFavorite by rememberSaveable {
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,
){
Card(
modifier=modifier,
shape = RoundedCornerShape(8.dp), //모서리 둥글게
elevation = 5.dp
){
Box (
modifier= Modifier.height(100.dp)
){
Image(
painter = painterResource(id = R.drawable.emergency),
contentDescription = "poster", //필수
contentScale = ContentScale.Crop
)
Box (
modifier= Modifier.fillMaxSize(),
contentAlignment = Alignment.TopEnd //오른쪽 위에
){
IconButton(onClick = {
onTabFavorite(!isFavorite) //onTabFavorite.invoke(!isFavorite) 인데 invoke는 생략아 가능
}) {
Icon(
imageVector = if(isFavorite) Icons.Default.Favorite else Icons.Default.FavoriteBorder,
contentDescription ="Favorite",
tint = Color.White
)
}
}
}
}
}
ImageCard() 함수에 매개변수로 넣어주고 호출 할 때마다 원하는 방식으로 표시되게끔 해줄 수 있다.
'안드로이드 앱 개발 공부 > jetpack Compose' 카테고리의 다른 글
[jetpack compose] 제트팩 컴포즈로 탭 만들기 (1) | 2023.03.07 |
---|---|
JetPack Compose_Scaffold, TextField, Button, 구조분해, SnackBar, 코루틴 스코프 (0) | 2023.01.09 |
JetPack Compose_ 리스트, LazyColumn (0) | 2023.01.04 |
JetPack Compose_ Box (0) | 2022.12.22 |
JetPack Compose_ 컴포저블, 프리뷰 간단히 (0) | 2022.12.22 |
댓글