이번 과정에서는 이미 알고있는 것들을 적용하고 몇가지 힌트와 함께 새로운 개념을 배우것이다.
이 화면을 만들어 보자.
버튼을 아이콘으로 교체하기
- 하위 Icon과 IconButton 컴포저블을 함께 사용한다.
- 아이콘 리소스는 material-icons-extended 아티팩트에서 사용가능한 Icons.Filled.ExpandLess 및 Icons.Filled.ExpandMore를 사용한다. 다음의 코드라인을 app/build.gradle 파일의 의존성으로 추가한다.
implementation "androidx.compose.material:material-icons-extended:$compose_version"
- padding을 수정하여 정렬한다.
- 접근성을 위해 content description을 추가하자.
문자열 리소스 사용하기
“Show more” 및 “Show less” 에 대한 content description을 나타내고, 이를 if 문을 사용하여 간단히 추가하자.
contentDescription = if (expanded) "Show less" else "Show more"
하지만 하드코딩된 문자열은 좋지 못한 방법이고 strings.xml 파일로부터 가져오는 것이 좋다.
각 문자열에 대해 Extract string resource를 사용하자. 안드로이드 스튜디오에 있는 Context Actions에서 이런 작업을 자동으로 할 수 있다.
대안으로는 app/src/res/values/strings.xml 을 열고 다음의 라인을 추가하는 것이다.
<string name="show_less">Show less</string>
<string name="show_more">Show more</string>
더 보기 나타내기
각 카드 사이즈에 맞게 변경되도록 “Composem ipsum” 텍스트는 나타나거나 사라진다.
- 새로운 Text 컴포저블을 Column에 Greeting으로 추가하고 아이템이 확장될 때 보여줄 수 있도록 한다.
- extraPadding은 제거하고 대신에 animateContentSize를 Row에 추가한다. 이를 통해 수동으로 조작하기 어려운 애니메이션을 생성 작업을 자동화 한다. 또한, 이는 coerceAtLeast함수를 제거할 수 있도록 한다.
elevation 및 shapes
- shadow와 clip을 함께 사용하여 카드 처럼 보이게 만들 수 있다. 하지만 머테리얼 컴포저블에 포함된 Card라는 것이 존재한다.
최종 코드는 다음과 같다.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BasicsCodelabTheme {
MyApp()
}
}
}
}
@Composable
private fun MyApp() {
var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) }
if (shouldShowOnboarding) {
OnboardingScreen(onContinueClicked = { shouldShowOnboarding = false })
} else {
Greetings()
}
}
@Composable
private fun OnboardingScreen(onContinueClicked: () -> Unit) {
Surface {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Welcome to the Basics Codelab!")
Button(
modifier = Modifier.padding(vertical = 24.dp),
onClick = onContinueClicked
) {
Text("Continue")
}
}
}
}
@Composable
private fun Greetings(names: List<String> = List(1000) { "$it" } ) {
LazyColumn(modifier = Modifier.padding(vertical = 4.dp)) {
items(items = names) { name ->
Greeting(name = name)
}
}
}
@Composable
private fun Greeting(name: String) {
Card(
backgroundColor = MaterialTheme.colors.primary,
modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp)
) {
CardContent(name)
}
}
@Composable
private fun CardContent(name: String) {
var expanded by remember { mutableStateOf(false) }
Row(
modifier = Modifier
.padding(12.dp)
.animateContentSize(
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
) {
Column(
modifier = Modifier
.weight(1f)
.padding(12.dp)
) {
Text(text = "Hello, ")
Text(
text = name,
style = MaterialTheme.typography.h4.copy(
fontWeight = FontWeight.ExtraBold
)
)
if (expanded) {
Text(
text = ("Composem ipsum color sit lazy, " +
"padding theme elit, sed do bouncy. ").repeat(4),
)
}
}
IconButton(onClick = { expanded = !expanded }) {
Icon(
imageVector = if (expanded) Filled.ExpandLess else Filled.ExpandMore,
contentDescription = if (expanded) {
stringResource(R.string.show_less)
} else {
stringResource(R.string.show_more)
}
)
}
}
}
@Preview(
showBackground = true,
widthDp = 320,
uiMode = UI_MODE_NIGHT_YES,
name = "DefaultPreviewDark"
)
@Preview(showBackground = true, widthDp = 320)
@Composable
fun DefaultPreview() {
BasicsCodelabTheme {
Greetings()
}
}
@Preview(showBackground = true, widthDp = 320, heightDp = 320)
@Composable
fun OnboardingPreview() {
BasicsCodelabTheme {
OnboardingScreen(onContinueClicked = {})
}
}
0개의 댓글