Skip to content

Commit

Permalink
add nav rail for large screen devices
Browse files Browse the repository at this point in the history
  • Loading branch information
ashnohe committed Mar 19, 2024
1 parent 07817f8 commit e811ef8
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 40 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ dependencies {
implementation(libs.compose.ui.tooling.preview)
implementation(libs.compose.material3)
implementation(libs.compose.material.icons)
implementation(libs.compose.material3.windowsizeclass)
androidTestImplementation(libs.compose.ui.test)
debugImplementation(libs.compose.ui.tooling)
debugImplementation(libs.compose.ui.test.manisfest)
Expand Down
164 changes: 124 additions & 40 deletions app/src/main/java/com/google/android/samples/socialite/ui/home/Home.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package com.google.android.samples.socialite.ui.home

import androidx.annotation.StringRes
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ChatBubbleOutline
Expand All @@ -26,10 +28,15 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationRail
import androidx.compose.material3.NavigationRailItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -38,6 +45,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
Expand All @@ -48,11 +56,27 @@ import androidx.navigation.compose.rememberNavController
import com.google.android.samples.socialite.R
import com.google.android.samples.socialite.ui.AnimationConstants
import com.google.android.samples.socialite.ui.home.timeline.Timeline
import com.google.android.samples.socialite.ui.player.findActivity

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@Composable
fun Home(
onChatClicked: (chatId: Long) -> Unit,
modifier: Modifier = Modifier,
) {
val windowSizeClass = calculateWindowSizeClass(
activity = LocalContext.current.findActivity()
).widthSizeClass
when (windowSizeClass) {
WindowWidthSizeClass.Compact -> CompactScreen(modifier, onChatClicked)
else -> LargeScreen(onChatClicked = onChatClicked)
}
}

@Composable
private fun CompactScreen(
modifier: Modifier,
onChatClicked: (chatId: Long) -> Unit
) {
var destination by rememberSaveable { mutableStateOf(Destination.Chats) }
Scaffold(
Expand All @@ -65,47 +89,26 @@ fun Home(
)
},
) { innerPadding ->
val navController = rememberNavController()
HomeBackground(modifier = Modifier.fillMaxSize())
NavHost(
navController = navController,
startDestination = destination.route,
HomeContent(innerPadding, modifier, destination, onChatClicked)
}
}

@Composable
private fun LargeScreen(
modifier: Modifier = Modifier,
onChatClicked: (chatId: Long) -> Unit
) {
var destination by rememberSaveable { mutableStateOf(Destination.Chats) }
Row(modifier = Modifier.fillMaxSize()) {
HomeNavigationRail(
currentDestination = destination.route,
onDestinationChanged = { destination = it }
)
Scaffold(
modifier = modifier,
) {
composable(
route = Destination.Timeline.route,
enterTransition = { AnimationConstants.enterTransition },
exitTransition = { AnimationConstants.exitTransition },
) {
Timeline(
contentPadding = innerPadding,
modifier = modifier,
)
}
composable(
route = Destination.Chats.route,
enterTransition = { AnimationConstants.enterTransition },
exitTransition = { AnimationConstants.exitTransition },
) {
val viewModel: HomeViewModel = hiltViewModel()
val chats by viewModel.chats.collectAsStateWithLifecycle()
ChatList(
chats = chats,
contentPadding = innerPadding,
onChatClicked = onChatClicked,
modifier = modifier,
)
}
composable(
route = Destination.Settings.route,
enterTransition = { AnimationConstants.enterTransition },
exitTransition = { AnimationConstants.exitTransition },
) {
Settings(
contentPadding = innerPadding,
modifier = Modifier.fillMaxSize(),
)
}
topBar = { HomeAppBar(title = stringResource(destination.label)) }
) {innerPadding ->
HomeContent(innerPadding, modifier, destination, onChatClicked)
}
}
}
Expand All @@ -125,6 +128,57 @@ private fun HomeAppBar(
)
}

@Composable
private fun HomeContent(
innerPadding: PaddingValues,
modifier: Modifier,
destination: Destination,
onChatClicked: (chatId: Long) -> Unit
){
val navController = rememberNavController()
HomeBackground(modifier = Modifier.fillMaxSize())
NavHost(
navController = navController,
startDestination = destination.route,
modifier = modifier,
) {
composable(
route = Destination.Timeline.route,
enterTransition = { AnimationConstants.enterTransition },
exitTransition = { AnimationConstants.exitTransition },
) {
Timeline(
contentPadding = innerPadding,
modifier = modifier,
)
}
composable(
route = Destination.Chats.route,
enterTransition = { AnimationConstants.enterTransition },
exitTransition = { AnimationConstants.exitTransition },
) {
val viewModel: HomeViewModel = hiltViewModel()
val chats by viewModel.chats.collectAsStateWithLifecycle()
ChatList(
chats = chats,
contentPadding = innerPadding,
onChatClicked = onChatClicked,
modifier = modifier,
)
}
composable(
route = Destination.Settings.route,
enterTransition = { AnimationConstants.enterTransition },
exitTransition = { AnimationConstants.exitTransition },
) {
Settings(
contentPadding = innerPadding,
modifier = Modifier.fillMaxSize(),
)
}
}
}

private enum class Destination(
val route: String,
@StringRes val label: Int,
Expand Down Expand Up @@ -176,3 +230,33 @@ private fun HomeNavigationBar(
}
}
}

@Composable
private fun HomeNavigationRail(
currentDestination: String,
onDestinationChanged: (Destination) -> Unit,
modifier: Modifier = Modifier,
) {
NavigationRail(
modifier = modifier
) {
for (destination in Destination.values()) {
val selected = currentDestination == destination.route
val label = stringResource(destination.label)
NavigationRailItem(
selected = selected,
onClick = { onDestinationChanged(destination) },
icon = {
Icon(
imageVector = destination.imageVector,
contentDescription = label,
)
},
label = {
Text(text = label)
},
alwaysShowLabel = false,
)
}
}
}
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ truth = "1.1.3"
turbine = "1.0.0"
uiautomator = "2.2.0"
window = "1.2.0"
windowSizeClass = "1.2.1"

[libraries]
accompanist-painter = { group = "com.google.accompanist", name = "accompanist-drawablepainter", version.ref = "accompanist" }
Expand All @@ -62,6 +63,7 @@ coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coi
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" }
compose-material-icons = { group = "androidx.compose.material", name = "material-icons-extended" }
compose-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
compose-material3-windowsizeclass = {group = "androidx.compose.material3", name = "material3-window-size-class", version.ref = "windowSizeClass"}
compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
compose-ui = { group = "androidx.compose.ui", name = "ui" }
compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
Expand Down

0 comments on commit e811ef8

Please sign in to comment.