Day 27 Compose UI Drawer
今年的疫情蠻嚴重的,希望大家都過得安好,希望疫情快點結束,能回到一些線下技術聚會的時光~
今天目標:了解 Compose UI 上 Drawer 怎麼使用。
Drawer的需求也是蠻常見的,今天的完成圖如下:
profile 圖是沿用 Day 7的~
我覺得這部分的程式碼跟昨天比起來,相對容易了解~
程式如下:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppMainScreen()
}
}
sealed class DrawerScreens(val title: String, val route: String) {
object Home : DrawerScreens("Home", "home")
object Account : DrawerScreens("Account", "account")
object Help : DrawerScreens( "Help", "help")
}
private val screens = listOf(
DrawerScreens.Home,
DrawerScreens.Account,
DrawerScreens.Help
)
@Composable
open fun AppMainScreen() {
val navController = rememberNavController()
Surface(color = MaterialTheme.colors.background) {
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
val openDrawer = {
scope.launch {
drawerState.open()
}
}
ModalDrawer(
drawerState = drawerState,
gesturesEnabled = drawerState.isOpen,
drawerContent = {
Drawer(
onDestinationClicked = { route ->
scope.launch {
drawerState.close()
}
navController.navigate(route) {
popUpTo = navController.graph.startDestinationId
launchSingleTop = true
}
}
)
}
) {
NavHost(
navController = navController,
startDestination = DrawerScreens.Home.route
) {
composable(DrawerScreens.Home.route) {
Home(
openDrawer = {
openDrawer()
}
)
}
composable(DrawerScreens.Account.route) {
Account(
openDrawer = {
openDrawer()
}
)
}
composable(DrawerScreens.Help.route) {
Help(
navController = navController
)
}
}
}
}
}
@Composable
fun Drawer(
modifier: Modifier = Modifier,
onDestinationClicked: (route: String) -> Unit
) {
Column(
modifier
.fillMaxSize()
.padding(start = 24.dp, top = 48.dp)
) {
Image(
painter = painterResource(R.drawable.profile_picture),
contentDescription = "App icon"
)
screens.forEach { screen ->
Spacer(Modifier.height(24.dp))
Text(
text = screen.title,
style = MaterialTheme.typography.h4,
modifier = Modifier.clickable {
onDestinationClicked(screen.route)
}
)
}
}
}
@Composable
fun TopBar(title: String = "", buttonIcon: ImageVector, onButtonClicked: () -> Unit) {
TopAppBar(
title = {
Text(
text = title
)
},
navigationIcon = {
IconButton(onClick = { onButtonClicked() } ) {
Icon(buttonIcon, contentDescription = "")
}
},
backgroundColor = MaterialTheme.colors.primaryVariant
)
}
@Composable
fun Home(openDrawer: () -> Unit) {
Column(modifier = Modifier.fillMaxSize()) {
TopBar(
title = "Home",
buttonIcon = Icons.Filled.Menu,
onButtonClicked = { openDrawer() }
)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Home Page content here.")
}
}
}
@Composable
fun Account(openDrawer: () -> Unit) {
Column(modifier = Modifier.fillMaxSize()) {
TopBar(
title = "Account",
buttonIcon = Icons.Filled.Menu,
onButtonClicked = { openDrawer() }
)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Account.", style = MaterialTheme.typography.h4)
}
}
}
@Composable
fun Help(navController: NavController) {
Column(modifier = Modifier.fillMaxSize()) {
TopBar(
title = "Help",
buttonIcon = Icons.Filled.ArrowBack,
onButtonClicked = { navController.popBackStack() }
)
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Help.", style = MaterialTheme.typography.h4)
}
}
}
我覺得 Drawer 這個元件在概念上最簡單的實現方式,
就是把就是把昨天的 Navigation 加上一層左邊的 Comlumn 顯示?
不過我還是查了一下相關資料,原來還有其他的延伸做法~放在參考資料區,有興趣的人在自己研究看看囉~理解的話今天就結束了~
然後,明天見囉!
參考資料:
https://proandroiddev.com/navigation-drawer-using-jetpack-compose-27ea7db74903
https://medium.com/android-news/exploring-drawers-in-jetpack-compose-3131e6f1b07b
本文同步發表在 Medium 上 文章連結