add wide navbar
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package ru.shadowsparky.ui
|
package ru.shadowsparky.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.focusGroup
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
@@ -23,16 +24,27 @@ import androidx.compose.material3.SnackbarHostState
|
|||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
|
import androidx.compose.material3.WideNavigationRail
|
||||||
|
import androidx.compose.material3.WideNavigationRailItem
|
||||||
|
import androidx.compose.material3.WideNavigationRailValue
|
||||||
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2
|
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2
|
||||||
|
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuite
|
||||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteItem
|
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteItem
|
||||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
|
|
||||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffoldDefaults
|
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffoldDefaults
|
||||||
|
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffoldLayout
|
||||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
|
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
|
||||||
|
import androidx.compose.material3.rememberWideNavigationRailState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
@@ -84,11 +96,13 @@ fun <T : Route> AppScaffold(
|
|||||||
) {
|
) {
|
||||||
val navigationSuiteType = when {
|
val navigationSuiteType = when {
|
||||||
navigationEntries.isNullOrEmpty() -> NavigationSuiteType.None
|
navigationEntries.isNullOrEmpty() -> NavigationSuiteType.None
|
||||||
else -> { NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(currentWindowAdaptiveInfoV2()) }
|
else -> NavigationSuiteScaffoldDefaults.navigationSuiteType(currentWindowAdaptiveInfoV2())
|
||||||
}
|
}
|
||||||
val blurState = rememberBlurState()
|
val blurState = rememberBlurState()
|
||||||
CompositionLocalProvider(LocalBlurState provides blurState) {
|
CompositionLocalProvider(LocalBlurState provides blurState) {
|
||||||
when (navigationSuiteType) {
|
when (navigationSuiteType) {
|
||||||
|
NavigationSuiteType.ShortNavigationBarCompact,
|
||||||
|
NavigationSuiteType.ShortNavigationBarMedium,
|
||||||
NavigationSuiteType.NavigationBar -> {
|
NavigationSuiteType.NavigationBar -> {
|
||||||
BottomBarScaffold(
|
BottomBarScaffold(
|
||||||
modifier,
|
modifier,
|
||||||
@@ -118,6 +132,7 @@ fun <T : Route> AppScaffold(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun <T : Route> DynamicNavigationScaffold(
|
private fun <T : Route> DynamicNavigationScaffold(
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
@@ -126,28 +141,67 @@ private fun <T : Route> DynamicNavigationScaffold(
|
|||||||
currentRoute: T?,
|
currentRoute: T?,
|
||||||
onSelectNavigation: ((T) -> Unit)?,
|
onSelectNavigation: ((T) -> Unit)?,
|
||||||
scrollBehavior: TopAppBarScrollBehavior?,
|
scrollBehavior: TopAppBarScrollBehavior?,
|
||||||
appBar: @Composable ((TopAppBarScrollBehavior?) -> Unit),
|
appBar: @Composable (TopAppBarScrollBehavior?) -> Unit,
|
||||||
snackbarState: SnackbarHostState?,
|
snackbarState: SnackbarHostState?,
|
||||||
content: @Composable ((PaddingValues) -> Unit)
|
content: @Composable (PaddingValues) -> Unit,
|
||||||
) {
|
) {
|
||||||
NavigationSuiteScaffold(
|
val entries = navigationEntries.orEmpty()
|
||||||
|
val isWideRail = navigationSuiteType == NavigationSuiteType.WideNavigationRailCollapsed ||
|
||||||
|
navigationSuiteType == NavigationSuiteType.WideNavigationRailExpanded
|
||||||
|
val railState = rememberWideNavigationRailState(
|
||||||
|
initialValue = WideNavigationRailValue.Collapsed
|
||||||
|
)
|
||||||
|
var railHasFocus by remember { mutableStateOf(false) }
|
||||||
|
LaunchedEffect(railHasFocus) {
|
||||||
|
if (railHasFocus) railState.expand() else railState.collapse()
|
||||||
|
}
|
||||||
|
NavigationSuiteScaffoldLayout(
|
||||||
navigationSuiteType = navigationSuiteType,
|
navigationSuiteType = navigationSuiteType,
|
||||||
navigationItems = {
|
navigationSuite = {
|
||||||
navigationEntries.orEmpty().forEach { entry ->
|
if (isWideRail) {
|
||||||
NavigationSuiteItem(
|
WideNavigationRail(
|
||||||
navigationSuiteType = navigationSuiteType,
|
state = railState,
|
||||||
selected = currentRoute == entry.route,
|
modifier = Modifier.onFocusChanged { railHasFocus = it.hasFocus }
|
||||||
onClick = { onSelectNavigation?.invoke(entry.route) },
|
.focusGroup(),
|
||||||
icon = { Icon(entry.painter, entry.title) },
|
) {
|
||||||
label = {
|
entries.forEach { entry ->
|
||||||
when (navigationSuiteType) {
|
WideNavigationRailItem(
|
||||||
NavigationSuiteType.NavigationDrawer -> Text(entry.title)
|
railExpanded =
|
||||||
}
|
railState.targetValue == WideNavigationRailValue.Expanded,
|
||||||
},
|
selected = currentRoute == entry.route,
|
||||||
modifier = Modifier.focusBorder(false, CircleShape)
|
onClick = {
|
||||||
)
|
onSelectNavigation?.invoke(entry.route)
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
Icon(entry.painter, entry.title)
|
||||||
|
},
|
||||||
|
label = { Text(entry.title) },
|
||||||
|
modifier = Modifier.focusBorder(false, CircleShape)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NavigationSuite(navigationSuiteType = navigationSuiteType) {
|
||||||
|
entries.forEach { entry ->
|
||||||
|
NavigationSuiteItem(
|
||||||
|
navigationSuiteType = navigationSuiteType,
|
||||||
|
selected = currentRoute == entry.route,
|
||||||
|
onClick = {
|
||||||
|
onSelectNavigation?.invoke(entry.route)
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
painter = entry.painter,
|
||||||
|
contentDescription = entry.title,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
label = { Text(entry.title) },
|
||||||
|
modifier = Modifier.focusBorder(false, CircleShape)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = if (scrollBehavior != null) {
|
modifier = if (scrollBehavior != null) {
|
||||||
@@ -156,7 +210,9 @@ private fun <T : Route> DynamicNavigationScaffold(
|
|||||||
modifier
|
modifier
|
||||||
},
|
},
|
||||||
topBar = { appBar(scrollBehavior) },
|
topBar = { appBar(scrollBehavior) },
|
||||||
snackbarHost = { snackbarState?.let { SnackbarHost(it) } },
|
snackbarHost = {
|
||||||
|
snackbarState?.let { SnackbarHost(it) }
|
||||||
|
},
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user