ã¯ããã«
Android Studioã§ããµãã¢ã¸ã¥ã¼ã«ã®Gitã表示ãããªãå ´åã®å¯¾çã解説ã
æ¹æ³
å·¦ä¸ã®Android Studio
âSettingsâ¦
âVersion Control
âDirectory Mappings
âãµãã¢ã¸ã¥ã¼ã«ã追å
Android Studioã§ããµãã¢ã¸ã¥ã¼ã«ã®Gitã表示ãããªãå ´åã®å¯¾çã解説ã
å·¦ä¸ã®Android Studio
âSettingsâ¦
âVersion Control
âDirectory Mappings
âãµãã¢ã¸ã¥ã¼ã«ã追å
Android Studioã®ããã¸ã§ã¯ãã«ã©ã¼å¤æ´æ¹æ³ã«ã¤ãã¦è§£èª¬ã
Change Project Color
ã«ã«ã¼ã½ã«ãåããã
Android Jetpack Composeã§ModalBottomSheet
ã使ç¨ããéãã¹ãã¼ã¿ã¹ãã¼ã®è²ãå¤æ´ããããã¨ãããã
â»ã¹ãã¼ã¿ã¹ãã¼ã¨ã¯ãç»é¢ä¸é¨ã«è¡¨ç¤ºãããã¢ã¤ã³ã³(æå»ã»ããããªã¼æ®éãªã©)ã並ãã é åã®ãã¨ã
ModalBottomSheet
ã¡ã½ããå
ã§isAppearanceLightStatusBars
ã®å¤ãå¤æ´ãã¦ããã®ãåå ã
WindowCompat.getInsetsController(window, window.decorView).apply { isAppearanceLightStatusBars = !darkThemeEnabled isAppearanceLightNavigationBars = !darkThemeEnabled }
â»androidx.compose.material3:material3-android:1.3.1
ã©ã¤ãã©ãªã使ç¨(2024å¹´12ææç¹ã§ææ°ç)
ModalBottomSheet
ã¡ã½ããã®content
å
ã§ãå度isAppearanceLightStatusBars
ã®å¤ãå¤æ´ãããã(LocalView.current.parent as DialogWindowProvider).window
ã§window
ãåå¾ããã®ããã¤ã³ãã
ModalBottomSheet( onDismissRequest = { showBottomSheet = false }, sheetState = sheetState ) { //ã¹ãã¼ã¿ã¹ãã¼ãå¤æ´ val window = (LocalView.current.parent as DialogWindowProvider).window WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = false // Sheet content Button(onClick = { scope.launch { sheetState.hide() }.invokeOnCompletion { if (!sheetState.isVisible) showBottomSheet = false } }) { Text("Hide bottom sheet") } }
Android Jetpack Composeã§ãä¸ã¹ã¯ã¤ãã§ç»é¢ãéããæ¹æ³ã解説ãModalBottomSheet
ãç¨ããæ¹æ³ããããããã®è¨äºã§ã¯AnchoredDraggableState
ã«ããã¹ã¯ã¤ãæ¤ç¥ãã¦ç»é¢ãéããæ¹æ³ã«ã¤ãã¦è§£èª¬ã
ã¹ã¯ã¤ãç¶æ ãå®ç¾©ããã¯ã©ã¹ä½æã
enum class AnchorPos { Start, End; }
ã¢ã¼ãã«ç»é¢ãä½æ
@OptIn(ExperimentalFoundationApi::class) @Composable fun ModalScreen(navController: NavHostController) { val screenHeight = with(LocalDensity.current) { LocalConfiguration.current.screenHeightDp.dp.toPx() } val anchors = DraggableAnchors { AnchorPos.Start at 0f AnchorPos.End at screenHeight } // ãã©ãã°å¯è½ãªè·é¢ã¨ç¶æ ãè¨å® val draggableState = remember { AnchoredDraggableState( initialValue = AnchorPos.Start, anchors = anchors, positionalThreshold = { it * 0.5f }, velocityThreshold = { screenHeight * 0.5f }, snapAnimationSpec = SpringSpec(), decayAnimationSpec = exponentialDecay(), confirmValueChange = { when (it) { AnchorPos.Start -> {} AnchorPos.End -> { //è¤æ°åpopãè¡ããããã¨ãé²ããããç¾å¨ã®ç»é¢ã§ã®ã¿popãè¡ãã if (navController.currentDestination?.route == NavItem.MODAL.route) { navController.popBackStack() } } } true } ) } Box( modifier = Modifier .offset { IntOffset( x = 0, y = draggableState .requireOffset() .roundToInt() ) } .anchoredDraggable( state = draggableState, orientation = Orientation.Vertical ) .fillMaxSize() .background(Color.DarkGray), ) { //æ»ããã¿ã³ Button( onClick = { navController.popBackStack() }, colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent), contentPadding = PaddingValues(0.dp) ) { Icon( modifier = Modifier.size(32.dp), contentDescription = "Close", imageVector = Icons.Default.Close ) } } }
Android Jetpack Composeã§ãããã ããã²ã¼ã·ã§ã³& è¤æ°ããã¯ã¹ã¿ãã¯ã®å®è£ ã«ã¤ãã¦è§£èª¬ã
åããã ã¿ããã¨ã«ããã¯ã¹ã¿ãã¯ãä¿æã
ä¾ãã°ããã¼ã 1
âãã¼ã 2
âä»ã¿ãæ¼ä¸
âãã¼ã ã¿ãæ¼ä¸
ã®éããã¼ã 1
ã«é·ç§»ããã®ã§ã¯ãªãããã¼ã 2
ã«é·ç§»ãããã
ã¾ããç»é¢ã®Route
å®ç¾©ããããNavItem
enumã¯ã©ã¹ä½æã
enum class NavItem(val route: String, val icon: ImageVector) { //BottomNavigation HOME("Home", Icons.Default.Home), EMAIL("Email", Icons.Default.Email), SETTINGS("Settings", Icons.Default.Settings), //Screen HOME_1("Home_1", Icons.Default.Home), HOME_2("Home_2", Icons.Default.Home), EMAIL_1("Email_1", Icons.Default.Email), EMAIL_2("Email_2", Icons.Default.Email), SETTINGS_1("Settings_1", Icons.Default.Settings), SETTINGS_2("Settings_2", Icons.Default.Settings) }
次ã«ãç»é¢ä¸ã«è¡¨ç¤ºãããããã ããã²ã¼ã·ã§ã³ãä½æã
@Composable fun BottomNavigation(navController: NavHostController) { val items = listOf( NavItem.HOME, NavItem.EMAIL, NavItem.SETTINGS ) NavigationBar { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route items.forEach { item -> NavigationBarItem( icon = { Icon(item.icon, contentDescription = item.route) }, label = { Text(item.route) }, selected = currentRoute?.startsWith(item.route) == true, onClick = { navController.navigate(item.route) { popUpTo(navController.graph.findStartDestination().id) { saveState = true } launchSingleTop = true restoreState = true } } ) } } }
表示ç»é¢ãä½æã
//表示ç»é¢ @Composable fun ShowScreen(navController: NavHostController, navItem: NavItem, nextRoute: String?) { Column( modifier = Modifier .fillMaxSize() .padding(top = 360.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Row { //ã¢ã¤ã³ã³ Icon( modifier = Modifier.size(32.dp), imageVector = navItem.icon, contentDescription = navItem.route ) //ããã¹ã Text( modifier = Modifier.padding(start = 12.dp), text = navItem.route, fontSize = 28.sp ) } if (nextRoute != null) { //é²ããã¿ã³ Button( modifier = Modifier.padding(top = 20.dp), onClick = { navController.navigate(nextRoute) } ) { Text( text = "Next", fontSize = 24.sp ) } } else { //æ»ããã¿ã³ Button( modifier = Modifier.padding(top = 20.dp), onClick = { navController.popBackStack() } ) { Text( text = "Back", fontSize = 24.sp ) } } } }
æå¾ã«ãç»é¢é·ç§»ãä½æã
@Composable fun MainApp() { val navController = rememberNavController() Scaffold( //ããã ããã²ã¼ã·ã§ã³ bottomBar = { BottomNavigation(navController) } ) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { NavHost( navController = navController, startDestination = NavItem.HOME.route ) { //ãã¼ã navigation(startDestination = NavItem.HOME_1.route, route = NavItem.HOME.route) { composable(NavItem.HOME_1.route) { ShowScreen(navController, NavItem.HOME_1, NavItem.HOME_2.route) } composable(NavItem.HOME_2.route) { ShowScreen(navController, NavItem.HOME_2, null) } } //Eã¡ã¼ã« navigation(startDestination = NavItem.EMAIL_1.route, route = NavItem.EMAIL.route) { composable(NavItem.EMAIL_1.route) { ShowScreen(navController, NavItem.EMAIL_1, NavItem.EMAIL_2.route) } composable(NavItem.EMAIL_2.route) { ShowScreen(navController, NavItem.EMAIL_2, null) } } //è¨å® navigation(startDestination = NavItem.SETTINGS_1.route, route = NavItem.SETTINGS.route) { composable(NavItem.SETTINGS_1.route) { ShowScreen(navController, NavItem.SETTINGS_1, NavItem.SETTINGS_2.route) } composable(NavItem.SETTINGS_2.route) { ShowScreen(navController, NavItem.SETTINGS_2, null) } } } } } }
Android Jetpack Composeã§ã横ç»é¢ã§ã®ã«ã¡ã©ã«ããã¢ã¦ã(åãæ¬ ã)ã¨ãã¥ã¼ã被ããªãããã«ããæ¹æ³ã«ã¤ãã¦è§£èª¬ã
windowInsetsPadding(WindowInsets.displayCutout)
ã§paddingãè¨å®ã
Scaffold( modifier = Modifier.windowInsetsPadding(WindowInsets.displayCutout) ) { innerPadding -> //...(ç¥) }
Android Jetpack Composeã§ãåç´Sliderãä½æããæ¹æ³ã«ã¤ãã¦è§£èª¬ã
graphicsLayer
ã¨layout
ãä¸è¨ã®ããã«å¤æ´ãããã¨ã«ããå®è£
ã§ããã
@Composable fun MainView(modifier: Modifier = Modifier) { var value by remember { mutableFloatStateOf(0f) } Slider( modifier = modifier .graphicsLayer { rotationZ = 90f transformOrigin = TransformOrigin(0f, 0f) } .layout { measurable, constraints -> val placeable = measurable.measure( Constraints( minWidth = constraints.minHeight, maxWidth = constraints.maxHeight, minHeight = constraints.minWidth, maxHeight = constraints.maxHeight, ) ) layout(placeable.height, placeable.width) { placeable.place(0, -placeable.height) } }, value = value, onValueChange = { value = it } ) }