애니메이션 : icon 추가
Jetpack Compose를 사용한 간단한 애니메이션
오늘은 위의 페이지를 참고하여 저번에 만들었던 Woof앱에 애니메이션을 추가해보자
Icon 추가
만든 어플들을 빌드할 때마다 gradle이라는 친구를 본 적 있을 것이다
gradle은 빌드를 도와주는 빌드 툴이다
compile, test, packaging, deploy & run과 같은 작업들을 자동화시켜준다
material design에는 icon이 있는데
이 icon들을 사용하려면 gradle에 dependency를 추가해줘야 한다
위와 같이 build.gradle (Module. Woof.app)에 들어가서
밑에 있는 dependencies 안에
implementation "androidx.compose.material:material-icons-extended:$compose_version"
을 입력해주자
그리고 위에 뜨는 Sync Now를 클릭해서 적용해주자
그리고 MainActivity.kt로 돌아와서
DogItem composable 밑에 DogItemButton composable을 추가하고
IconButton이라는 composable을 이용해서 다음과 같이 작성해보자
@Composable
private fun DogItemButton(
expanded: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier
){
IconButton(onClick = onClick) {
Icon(
imageVector = Icons.Filled.ExpandMore,
tint = MaterialTheme.colors.secondary,
contentDescription = stringResource(R.string.expand_button_content_description)
)
}
}
전에 Icon이 Image와 뭐가 다른가 의아했었는데
vector 이미지를 담을 수도 있다는 걸 알 수 있다
그리고 이제 DogItem에 버튼이 클릭되었는지 상태를 저장하는 remember 변수 하나랑
아이콘을 띄우는 구문, 그리고 버튼을 오른쪽 끝으로 정렬할 수 있게 Spcaer를 추가해보자
@Composable
fun DogItem(dog: Dog, modifier: Modifier = Modifier) {
var expanded by remember { mutableStateOf(false) }
Card(
modifier = Modifier.padding(8.dp),
elevation = 4.dp
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
DogIcon(dog.imageResourceId)
DogInformation(dog.name, dog.age)
Spacer(Modifier.weight(1f))
DogItemButton(
expanded = expanded,
onClick = {}
)
}
}
}
Modifier.weight를 정말 오랜만에 보는 것 같은데
여기서 가중치가 들어간 건 Spacer 하나이기 때문에
다른 모든 애들의 크기가 유지되는 선에서 모든 부피를 차지하게 된다
결과화면
아이콘 클릭 시 나올 화면 구성
클릭하면 강아지의 취미 정보를 담은 Text를 보여줘야 한다
다음과 같은 DogHobby composable을 작성한다
@Composable
fun DogHobby(@StringRes dogHobby: Int, modifier: Modifier = Modifier){
Column(
modifier.padding(
start = 16.dp,
top = 8.dp,
bottom = 16.dp,
end = 16.dp
)
){
Text(
text = stringResource(R.string.about),
style = MaterialTheme.typography.h3
)
Text(
text = stringResource(dogHobby),
style = MaterialTheme.typography.body1
)
}
}
그리고 이 DogHobby를 DogItem에 넣어야 하기 때문에
Row와 동등한 관계에 DogHobby를 위치시키고 Column으로 감싸준다
@Composable
fun DogItem(dog: Dog, modifier: Modifier = Modifier) {
var expanded by remember { mutableStateOf(false) }
Card(
modifier = Modifier.padding(8.dp),
elevation = 4.dp
) {
Column {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
DogIcon(dog.imageResourceId)
DogInformation(dog.name, dog.age)
Spacer(Modifier.weight(1f))
DogItemButton(
expanded = expanded,
onClick = {}
)
}
DogHobby(dog.hobbies)
}
}
}
결과화면
버튼 기능 추가
버튼 기능을 추가하려면 expanded 변수만 고민해보면 된다
일단 DogItemButton의 onclick에서 expanded의 참 거짓을 바꿀 수 있게 설정해주고
DogHobby가 expanded가 참일 때만 보이게 하고
expanded가 참일 때에는 아래를 가르키는 화살표 아이콘(ExpandMore)이 아니라
위를 가르키는 화살표 아이콘(ExpandLess)이 되도록 해줘야 한다
DogItem의 Column안에서 onClick과 DogHobby 출력 여부 결정
Column {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
DogIcon(dog.imageResourceId)
DogInformation(dog.name, dog.age)
Spacer(Modifier.weight(1f))
DogItemButton(
expanded = expanded,
onClick = { expanded = !expanded }
)
}
if(expanded) { DogHobby(dog.hobbies) }
}
DogItemButton의 Icon에서의 imageVector
Icon(
imageVector = if(expanded) Icons.Filled.ExpandLess else Icons.Filled.ExpandMore,
tint = MaterialTheme.colors.secondary,
contentDescription = stringResource(R.string.expand_button_content_description)
)
결과화면
애니메이션 추가
DogHobby의 높이가 변경되는 애니메이션을 추가하고 싶은 것이기 때문에
animateContentSize를 이용한다
애니메이션 사양을 설정할 수 있는 AnimationSpec도 이용한다
우리는 DogHobby가 spring처럼 튀는 느낌의 애니메이션을 추가할 것이다
DogItem의 Column 안에 다음과 같이 작성한다
Column(
modifier.animateContentSize(
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
)
dampingRatio는 용수철의 탄성(=얼마나 통통 튀는가)
stiffness는 용수철의 속도(=얼마나 빨리 돌아오는가)
를 결정하는 인자이다
결과화면
+ 색이 변하는 애니메이션 추가하기
animate어쩌구AsState는 최종값을 넣어주면
현재값에서 최종값으로의 애니메이션이 적용된다
DogItem에 다음과 같이 remember랑 비슷하게 만들어주고
val expandedColor by animateColorAsState(
targetValue = if(expanded) MaterialTheme.colors.primary else MaterialTheme.colors.surface
)
DogItem의 Column안에서 background 색으로 지정해주면 된다
Column(
modifier
.animateContentSize(
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
.background(expandedColor),
)
결과화면
'기타 > 안드로이드' 카테고리의 다른 글
30. SuperHero App: Material Design, App Icon 복습 (0) | 2022.11.06 |
---|---|
29. 앱의 접근성 개선 (0) | 2022.11.06 |
27. Woof App : Material Design (0) | 2022.10.29 |
26. Course App : Grid 구성 (0) | 2022.10.21 |
Android Studio에서 emulator 녹화하는 방법 (2) | 2022.10.15 |