Material Design
๋์งํธ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํฌ๊ด์ ์ธ ๋์์ธ ์์คํ
Color, Typography, Shape ๋ฑ
@Composable
fun MaterialTheme(
colors: Colors,
typography: Typography,
shapes: Shapes,
content: @Composable () -> Unit
)
val customTextSelectionColors = TextSelectionColors(
handleColor = colorResource(id = R.color.primary100),
backgroundColor = Color(0xFF4286F4).copy(alpha = 0.4f)
)
CompositionLocalProvider(LocalTextSelectionColors provides customTextSelectionColors) {
BasicTextField(
value = input,
onValueChange = { input = it },
)
}
composable์ ๊ณ์ธต์ด ๊น๊ฑฐ๋, ๋์ผํ param์ ์ฌ๋ฌ ๊ณณ์์ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ CompositionLocal์ ํตํด์ ์๋ฌต์ ์ผ๋ก ํด๋น ๊ฐ์ ๋๊ฒจ์ค ์ ์์
https://developer.android.com/jetpack/compose/compositionlocal?hl=ko
Animate*AsState
- animateColorAsState :: ์์๊ฐ์ ๋ณ๊ฒฝํ์ ๋ ์ด๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ํํํ๊ธฐ ์ํ state
Animating Visibility
- AnimatedVisibility :: composable์ด ๋ณด์ฌ์ง๊ณ ์ฌ๋ผ์ง๋ ๊ณผ์ ์ ์ ๋๋ฉ์ด์ ์ผ๋ก ํํ
- slideInVertically
- animationSpec
- tween
- spring
Animating content size change
- animateContentSize :: composable ํจ์ ๋ด๋ถ์ ์ฌ์ด์ฆ๊ฐ ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ปจํ ์ธ ๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ๋์ ์ผ๋ก ์ฌ์ด์ฆ ๋ณํ๋ฅผ ์ ๋๋ฉ์ด์ ์ผ๋ก ์ฒ๋ฆฌ
Multiple value animation
- Transition
Repeated animation
- InfiniteTransition :: ๊ณ์ํด์ ๋ฐ๋ณตํ๋ ์ ๋๋ฉ์ด์ ์ฒ๋ฆฌ
Gesture animation
- Animatable
NavController
→ Stateful
→ ์ฑ์ ํ๋ฉด๊ณผ ๊ฐ ํ๋ฉด ์ํ๋ฅผ ๊ตฌ์ฑํ๋ Composable์ ๋ฐฑ์คํ ์ ์ง
- rememberNavController() ๋ฅผ ์ด์ฉํ์ฌ navController ์์ฑ ๊ฐ๋ฅ
NavHost
→ NavHost๋ NavController์ Navigation Graph ์ฐ๊ฒฐ
→ ๊ทธ๋ํ์ ์์๊ฒฝ๋ก๋ก ํ์
val navController = rememberNavController()
// ๊ฐ์ฅ ์์ Composable์ ๋ฑ๋ก
NavHost(
navController = navController,
startDestination = Screen.Overview.name,
modifier = Modifier.padding(innerPadding)
) {
composable(Screen.Overview.name) {
Text(Screen.Overview.name)
}
composable(Screen.Accounts.name) {
Text(Screen.Accounts.name)
}
}
val accountsName = Screen.Accounts.name
NavHost(
navController = navController,
startDestination = Screen.Overview.name,
modifier = Modifier.padding(innerPadding)
) {
composable(
"$accountsName/{name}",
arguments = listOf(
navArgument("name") {
type = NavType.StringType
}
),
deepLinks = listOf(navDeepLink {
uriPattern = "rally://$accountsName/{name}"
}) { entry ->
val accountName = entry.arguments?.getString("name")
val account = UserData.getAccount(accountName)
SingleAccountBody(account = account)
}
composable(Screen.Overview.name) {
OverviewBody(
onClickSeeAllBills = { navController.navigate(Bills.name) } //ํ๋ฉด ์ด๋
onAccountClick = { name ->
navController.navigate("${Accounts.name}/$name") //์ธ์ ์ ๋ฌ๊ณผ ํจ๊ป ์ด๋
}
}
composable(Screen.Accounts.name) {
AccountsBody(accounts = UserData.accounts) { name ->
navController.navigate("Accounts/$name}")
}
}
composable(Screen.Bills.name) {
BillsBody(bills = Userdata.bills)
}
}
xml์์ ComposeView๋ฅผ ์์ ฏ์ผ๋ก ์ฌ์ฉํ ์ ์์
composeView.setContent {
MaterialTheme {
PlantDetailDescription()
}
}
dimensionResource(R.dimen.-) ์ผ๋ก Rํ์ผ ๋ด ์์ฑํ ๊ฐ์ ๋ถ๋ฌ์ฌ ์ ์์
Composable ์๋ช ์ฃผ๊ธฐ
View๊ฐ ์๋์ฐ์์ ๋ถ๋ฆฌ๋ ๋๋ง๋ค Composition๋ฅผ ์ญ์ ํจ
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnViewTreeLifecylceDestroyed
)
// Fragment๊ฐ Destroy๋ ๋ Composition์ ์ญ์ ํ๊ธฐ ์ํด์ ์ค์
val selectedItem =
AndroidView(
factory = { context ->
CustomView(context).apply { // View setup }
},
update = { view ->
// View ์
๋ฐ์ดํธ ๋ก์ง ์ถ๊ฐ
view.coordinator.selectedItem = selectedItem.value
}
)
// ๊ตฌ์ฑํ View๋ฅผ ์ป๊ธฐ ์ํด์ ํ ๋ฒ ํธ์ถ๋จ
// factory ๋ธ๋ก์ ์ผํ์ฑ์ผ๋ก ์ด๊ธฐํํ๊ฑฐ๋ ์์ฑ ์ค์ ํ ๋ ์ํ ๊ฐ๋ฅ
// update ๋ธ๋ก์ ์ฌ๊ตฌ์ฑ์ผ๋ก ์ธํด ์ฌ๋ฌ ๋ฒ UI thread์์๋ ์คํ๋ ์ ์์
'What I Learned' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Android Compose ์คํฐ๋ ๊ธฐ๋ก 02 (0) | 2023.10.20 |
---|---|
Android Compose ์คํฐ๋ ๊ธฐ๋ก 01 (0) | 2023.10.19 |
NoSQL ์ดํดํ๊ธฐ (0) | 2023.06.28 |