2022年9月25日日曜日

AndroidViewBinding

implementation "androidx.compose.ui:ui-viewbinding:$compose_version" AndroidViewBinding( factory = ListItemBinding::inflate, update = { ... }, modifier = ..., ) AndroidViewBinding( factory = { inflater, parent, attachToParent -> ListItemBinding.inflate(inflater, parent, attachToParent).apply { ... } }, update = { ... }, modifier = ..., )

2022年9月17日土曜日

derivedStateOf の効果を LayoutInspector の composition count で確認する

derivedStateOf を使っていない、よくないコード val state = rememberLazyListState() // TODO derivedStateOf を使う val showScrollToTopButton= state.firstVisibleItemIndex > 0 LazyColumn( state = state, modifier = Modifier.fillMaxSize() ) { ... } if (showScrollToTopButton) { Button( onClick = { ... }, ... ) { Text("scroll to top") } }
LayoutInspector で Button が表示されたあともスクロールのたびに recompose が走っているので Button の skip count が増えていっています。 val showScrollToTopButton by remember { derivedStateOf { state.firstVisibleItemIndex > 0 } } に変えると、スクロールのたびに recompose が走っていたのがなくなり、Button の skip count が増えなくなりました。



2022年8月20日土曜日

Accompanist の Navigation Material の BottomSheet で表示エリアにおさまるように配置する

Accompanist : Navigation Material @OptIn(ExperimentalMaterialNavigationApi::class) @Composable fun MyApp() { val bottomSheetNavigator = rememberBottomSheetNavigator() val navController = rememberNavController(bottomSheetNavigator) ModalBottomSheetLayout(bottomSheetNavigator) { MyNavHost(navController) } } @OptIn(ExperimentalMaterialNavigationApi::class) @Composable fun MyNavHost(navController: NavHostController) { NavHost( navController = navController, startDestination = "home" ) { composable(route = "home") { Button(onClick = { navController.navigate("sheet") }) { Text("show bottom sheet") } } bottomSheet(route = "sheet") { Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize() ) { Spacer( modifier = Modifier .size(100.dp) .background(Color.Blue) ) } } } } この場合、Blue の四角は Bottom Sheet を完全に展開したときの中心に配置されます。
rememberNavController に指定した BottomSheetNavigator は NavHostController の navigatorProvider から取得できます。

BottomSheetNavigator の navigatorSheetState から BottomSheet の offset が取れるので、それを利用すると Blue の四角を BottomSheet の表示されている領域の中心に配置することができます。 @OptIn(ExperimentalMaterialNavigationApi::class) @Composable fun MyNavHost(navController: NavHostController) { NavHost( navController = navController, startDestination = "home" ) { composable(route = "home") { Button(onClick = { navController.navigate("sheet") }) { Text("show bottom sheet") } } bottomSheet(route = "sheet") { val bottomSheetNavigator = navController.navigatorProvider[BottomSheetNavigator::class] val offset = bottomSheetNavigator.navigatorSheetState.offset.value Column { Box( contentAlignment = Alignment.Center, modifier = Modifier .fillMaxWidth() .weight(1f) ) { Spacer( modifier = Modifier .size(100.dp) .background(Color.Blue) ) } with(LocalDensity.current) { Spacer(modifier = Modifier.height(offset.toDp())) } } } } }