Joel Crawford
01/16/2024, 3:33 PMJoel Crawford
01/16/2024, 3:40 PMclass MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MainScreen()
}
}
}
@Composable
fun MainScreen() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
val navController = rememberNavController()
Scaffold(
scaffoldState = scaffoldState,
topBar = { TopBar(scope = scope, scaffoldState = scaffoldState) },
drawerBackgroundColor = colorResource(id = R.color.colorPrimary),
drawerContent = {
Drawer(scope = scope, scaffoldState = scaffoldState, navController = navController)
},
backgroundColor = colorResource(id = R.color.colorPrimaryDark)
) { padding ->
Box(modifier = Modifier.padding(padding)) {
Navigation(navController = navController)
}
}
}
@Preview(showBackground = true)
@Composable
fun MainScreenPreview() {
MainScreen()
}
@Composable
fun TopBar(scope: CoroutineScope, scaffoldState: ScaffoldState) {
TopAppBar(
title = { Text(text = stringResource(R.string.app_name), fontSize = 18.sp) },
navigationIcon = {
IconButton(onClick = {
scope.launch {
scaffoldState.drawerState.open()
}
}) {
Icon(Icons.Filled.Menu, "")
}
},
backgroundColor = colorResource(id = R.color.colorPrimary),
contentColor = Color.White
)
}
@Preview(showBackground = false)
@Composable
fun TopBarPreview() {
val scope = rememberCoroutineScope()
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
TopBar(scope = scope, scaffoldState = scaffoldState)
}
@Composable
fun Drawer(scope: CoroutineScope, scaffoldState: ScaffoldState, navController: NavController) {
val items = listOf(
NavDrawerItem.Home,
NavDrawerItem.Music,
NavDrawerItem.Movies,
NavDrawerItem.Books,
NavDrawerItem.Profile,
NavDrawerItem.Settings
)
Column(
//Adding .verticalScroll( rememberScrollState()) makes the column scrollable
//For fixing the header, you can use different columns for the header image and the second column for thr drawer items and then
//.verticalScroll( rememberScrollState()) is added to the second column ie containing the drawer items
modifier = Modifier
.verticalScroll(
rememberScrollState()
)
) {
// Header
Image(
painter = painterResource(id = R.drawable.logo),
contentDescription = R.drawable.logo.toString(),
modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.padding(10.dp)
)
// Space between
Spacer(
modifier = Modifier
.fillMaxWidth()
.height(5.dp)
)
// List of navigation items
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
items.forEach { item ->
DrawerItem(item = item, selected = currentRoute == item.route, onItemClick = {
navController.navigate(item.route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
navController.graph.startDestinationRoute?.let { route ->
popUpTo(route) {
saveState = true
}
}
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
// Close drawer
scope.launch {
scaffoldState.drawerState.close()
}
})
}
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Developed by John Codeos",
color = Color.White,
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
modifier = Modifier
.padding(12.dp)
.align(Alignment.CenterHorizontally)
)
}
}
@Preview(showBackground = false)
@Composable
fun DrawerPreview() {
val scope = rememberCoroutineScope()
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val navController = rememberNavController()
Drawer(scope = scope, scaffoldState = scaffoldState, navController = navController)
}
@Composable
fun DrawerItem(item: NavDrawerItem, selected: Boolean, onItemClick: (NavDrawerItem) -> Unit) {
val background = if (selected) R.color.colorPrimaryDark else android.R.color.transparent
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = { onItemClick(item) })
.height(45.dp)
.background(colorResource(id = background))
.padding(start = 10.dp)
) {
Image(
painter = painterResource(id = item.icon),
contentDescription = item.title,
colorFilter = ColorFilter.tint(Color.White),
contentScale = ContentScale.Fit,
modifier = Modifier
.height(35.dp)
.width(35.dp)
)
Spacer(modifier = Modifier.width(7.dp))
Text(
text = item.title,
fontSize = 18.sp,
color = Color.White
)
}
}
@Preview(showBackground = false)
@Composable
fun DrawerItemPreview() {
DrawerItem(item = NavDrawerItem.Home, selected = false, onItemClick = {})
}
@Composable
fun Navigation(navController: NavHostController) {
NavHost(navController, startDestination = NavDrawerItem.Home.route) {
composable(NavDrawerItem.Home.route) {
HomeScreen(navController = navController)
}
composable("detail/{itemName}") { backStackEntry ->
val itemName = backStackEntry.arguments?.getString("itemName")
DetailScreen(itemName = itemName)
}
composable(NavDrawerItem.Music.route) {
MusicScreen()
}
composable(NavDrawerItem.Movies.route) {
MoviesScreen()
}
composable(NavDrawerItem.Books.route) {
BooksScreen()
}
composable(NavDrawerItem.Profile.route) {
ProfileScreen()
}
composable(NavDrawerItem.Settings.route) {
SettingsScreen()
}
}
}
Here is the code for the different Screens:
@Composable
fun HomeScreen(navController: NavController) {
Column(
modifier = Modifier
.fillMaxSize()
.background(colorResource(id = R.color.colorPrimaryDark))
.wrapContentSize(Alignment.Center)
) {
LazyColumn {
itemsIndexed(items = (0 until 30).toList()) { index, _ ->
ItemCardView(
itemName = "Testing Name ${(index + 1)}",
id = (index + 1),
onClick = {
navController.navigate("detail/Testing Name ${(index + 1)}")
})
}
}
}
}
@Preview(showBackground = true)
@Composable
fun HomeScreenPreview() {
HomeScreen(navController = NavController(LocalContext.current))
}
@Composable
fun MusicScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(colorResource(id = R.color.colorPrimaryDark))
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Music View",
fontWeight = FontWeight.Bold,
color = Color.White,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}
@Preview(showBackground = true)
@Composable
fun MusicScreenPreview() {
MusicScreen()
}
@Composable
fun MoviesScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(colorResource(id = R.color.colorPrimaryDark))
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Movies View",
fontWeight = FontWeight.Bold,
color = Color.White,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}
@Preview(showBackground = true)
@Composable
fun MoviesScreenPreview() {
MoviesScreen()
}
@Composable
fun BooksScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(colorResource(id = R.color.colorPrimaryDark))
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Books View",
fontWeight = FontWeight.Bold,
color = Color.White,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}
@Preview(showBackground = true)
@Composable
fun BooksScreenPreview() {
BooksScreen()
}
@Composable
fun ProfileScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(colorResource(id = R.color.colorPrimaryDark))
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Profile View",
fontWeight = FontWeight.Bold,
color = Color.White,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}
@Preview(showBackground = true)
@Composable
fun ProfileScreenPreview() {
ProfileScreen()
}
@Composable
fun SettingsScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(colorResource(id = R.color.colorPrimaryDark))
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Settings View",
fontWeight = FontWeight.Bold,
color = Color.White,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}
@Preview(showBackground = true)
@Composable
fun SettingsScreenPreview() {
SettingsScreen()
}
Chrimaeon
01/16/2024, 6:17 PMnavigationIcon
of your topbar and its onClick
. you get the current route via navController.currentBackStackEntry?.destination?.route
Joel Crawford
01/16/2024, 6:25 PMChrimaeon
01/16/2024, 6:28 PMChrimaeon
01/16/2024, 6:29 PMJoel Crawford
01/16/2024, 6:31 PMJoel Crawford
01/16/2024, 6:31 PMsindrenm
01/16/2024, 7:06 PMJoel Crawford
01/16/2024, 9:10 PMJoel Crawford
01/17/2024, 7:42 PM