Skip to content

Instantly share code, notes, and snippets.

@sonique6784
Last active December 19, 2022 20:37
Show Gist options
  • Save sonique6784/27627ce9d9a0d54724e5fc14a0df1733 to your computer and use it in GitHub Desktop.
Save sonique6784/27627ce9d9a0d54724e5fc14a0df1733 to your computer and use it in GitHub Desktop.
A proposition of handling BottomBar, NavRail and NavDrawer in a single-composable.
/* Copyright 2022 Cedric Ferry.
SPDX-License-Identifier: Apache-2.0 */
import android.content.res.Configuration.ORIENTATION_LANDSCAPE
import android.content.res.Configuration.ORIENTATION_PORTRAIT
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
open class NavigationItemData(
var label: @Composable () -> Unit,
var icon: @Composable () -> Unit,
val onClick: () -> Unit = {},
var selected: Boolean = false
)
enum class NavType {
BottomBar,
NavRail,
Drawer
}
@Composable
fun getNavType(windowSizeClass: WindowSizeClass): NavType {
val configuration = LocalConfiguration.current
return if (configuration.orientation == ORIENTATION_PORTRAIT) {
if (windowSizeClass.widthSizeClass == WindowWidthSizeClass.Compact) {
NavType.BottomBar
} else {
NavType.NavRail
}
} else if (configuration.orientation == ORIENTATION_LANDSCAPE) {
if (windowSizeClass.widthSizeClass == WindowWidthSizeClass.Compact) {
NavType.BottomBar
} else if (windowSizeClass.widthSizeClass == WindowWidthSizeClass.Medium) {
NavType.NavRail
} else if (windowSizeClass.widthSizeClass == WindowWidthSizeClass.Expanded) {
NavType.Drawer
} else {
NavType.BottomBar
}
} else {
NavType.BottomBar
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AutoNav(
windowSizeClass: NavType,
navContent: List<NavigationItemData>,
content: @Composable () -> Unit = {}
) {
if (windowSizeClass == NavType.BottomBar) {
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
) {
Column(modifier = Modifier.align(alignment = Alignment.TopCenter)) {
content()
}
NavigationBar(modifier = Modifier.align(alignment = Alignment.BottomCenter)) {
for (navItem in navContent) {
NavigationBarItem(
selected = navItem.selected,
onClick = navItem.onClick,
icon = navItem.icon
)
}
}
}
} else {
Row(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()
) {
if (windowSizeClass == NavType.NavRail) {
//https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#NavigationRail(androidx.compose.ui.Modifier,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,kotlin.Function1,androidx.compose.foundation.layout.WindowInsets,kotlin.Function1)
NavigationRail() {
for (navItem in navContent) {
NavigationRailItem(
selected = navItem.selected,
onClick = navItem.onClick,
icon = navItem.icon
)
}
}
content()
} else if (windowSizeClass == NavType.Drawer) {
//https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#ModalNavigationDrawer(kotlin.Function0,androidx.compose.ui.Modifier,androidx.compose.material3.DrawerState,kotlin.Boolean,androidx.compose.ui.graphics.Color,kotlin.Function0)
PermanentNavigationDrawer(drawerContent = {
ModalDrawerSheet {
Spacer(Modifier.height(12.dp))
for (navItem in navContent) {
NavigationDrawerItem(
selected = navItem.selected,
onClick = navItem.onClick,
icon = navItem.icon,
label = navItem.label
)
}
}
}) {
content()
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment