2023年3月16日木曜日

Compose の LottieAnimation でクリックしたときにアニメーションさせる

rememberLottieAnimatable を使います。 @Preview @Composable fun LottieAnimationSample() { val composition by rememberLottieComposition( LottieCompositionSpec.RawRes(R.raw.lottie_animation) ) val lottieAnimatable = rememberLottieAnimatable() val coroutineScope = rememberCoroutineScope() Box( contentAlignment = Alignment.Center, modifier = Modifier .fillMaxSize() .pointerInput(Unit) { detectTapGestures( onTap = { coroutineScope.launch { lottieAnimatable.animate(composition) } }, ) } ) { LottieAnimation( composition = composition, progress = { lottieAnimatable.value }, modifier = Modifier.size(72.dp), ) } }

2023年3月8日水曜日

Navigation Compose の optional arguments に null を渡したいときは query parameter 自体を消さないといけない

Navigation Compose の destination に optional arguments を設定する場合、nullable = true を設定します(もしくは defaultValue を設定する)。 composable( route = "detail?id={id}", arguments = listOf( navArgument("id") { type = NavType.StringType nullable = true } ) ) { この場合、NavHostController.navigate() に渡す文字列と id の値の関係は次のようになります。

destination 先での id の値
navController.navigate("detail")null
navController.navigate("detail?id=AAAAA")"AAAA"
navController.navigate("detail?id=")""
val id: String? = null
navController.navigate("detail?id=${id}")
"null"


注意しないといけないのは "detail?id=${id}" です。id 変数が null のとき、これは "detail?id=null" になり、destination 先では "null" という文字列が取得されてしまいます。

よって id 変数が null かどうかによって次のように navigate() に渡す文字列を変える必要があります。 if (id == null) { navController.navigate("detail") } else { navController.navigate("detail?id=${id}") }

挙動確認のコード @Composable fun NavigationSample() { val navController = rememberNavController() NavHost( navController = navController, startDestination = "home" ) { composable("home") { Column { Text("home") Button( onClick = { navController.navigate("detail") } ) { Text("detail") } Button( onClick = { navController.navigate("detail?id=AAAAA") } ) { Text("detail?id=AAAAA") } Button( onClick = { navController.navigate("detail?id=") } ) { Text("detail?id=") } val id: String? = null Button( onClick = { navController.navigate("detail?id=${id}") } ) { Text("detail?id=${id}") } } } composable( route = "detail?id={id}", arguments = listOf( navArgument("id") { type = NavType.StringType nullable = true } ) ) { Column { val arguments = requireNotNull(it.arguments) val id = arguments.getString("id") Text(text = "detail") Text(text = "id is null : ${id == null}") } } } }