Represent the Gallery screen hierarchy as a tree
This CL changes the Gallery app screens to be a tree instead of a list. This will allow adding sub-menus to the gallery app in case we want multiple different screens for a single feature, which is the case for the People activity/screens. Bug: 238993727 Test: Builds Change-Id: Idd28fd5a0fa79fd32ab1f8a95ed8c16fa2f465ac
This commit is contained in:
@@ -23,36 +23,38 @@ import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.android.systemui.compose.theme.SystemUITheme
|
||||
|
||||
enum class Screen {
|
||||
Home,
|
||||
Typography,
|
||||
MaterialColors,
|
||||
AndroidColors,
|
||||
ExampleFeature,
|
||||
/** The gallery app screens. */
|
||||
object GalleryAppScreens {
|
||||
val Typography = ChildScreen("typography") { TypographyScreen() }
|
||||
val MaterialColors = ChildScreen("material_colors") { MaterialColorsScreen() }
|
||||
val AndroidColors = ChildScreen("android_colors") { AndroidColorsScreen() }
|
||||
val ExampleFeature = ChildScreen("example_feature") { ExampleFeatureScreen() }
|
||||
|
||||
val Home =
|
||||
ParentScreen(
|
||||
"home",
|
||||
mapOf(
|
||||
"Typography" to Typography,
|
||||
"Material colors" to MaterialColors,
|
||||
"Android colors" to AndroidColors,
|
||||
"Example feature" to ExampleFeature,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** The main content of the app, that shows the [HomeScreen] by default. */
|
||||
/** The main content of the app, that shows [GalleryAppScreens.Home] by default. */
|
||||
@Composable
|
||||
private fun MainContent() {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
val navController = rememberNavController()
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = Screen.Home.name,
|
||||
startDestination = GalleryAppScreens.Home.identifier,
|
||||
) {
|
||||
composable(Screen.Home.name) {
|
||||
HomeScreen(
|
||||
onScreenSelected = { navController.navigate(it.name) },
|
||||
)
|
||||
}
|
||||
composable(Screen.Typography.name) { TypographyScreen() }
|
||||
composable(Screen.MaterialColors.name) { MaterialColorsScreen() }
|
||||
composable(Screen.AndroidColors.name) { AndroidColorsScreen() }
|
||||
composable(Screen.ExampleFeature.name) { ExampleFeatureScreen() }
|
||||
screen(GalleryAppScreens.Home, navController)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.compose.gallery
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/** The home screen shown when starting the app. */
|
||||
@Composable
|
||||
fun HomeScreen(onScreenSelected: (Screen) -> Unit) {
|
||||
LazyColumn(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Screen.values()
|
||||
.filter { it != Screen.Home }
|
||||
.forEach { screen ->
|
||||
item {
|
||||
Surface(
|
||||
Modifier.fillMaxWidth(),
|
||||
color = MaterialTheme.colorScheme.secondaryContainer,
|
||||
shape = CircleShape,
|
||||
) {
|
||||
Column(
|
||||
Modifier.clickable { onScreenSelected(screen) }.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(screen.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.compose.gallery
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.navigation
|
||||
|
||||
/**
|
||||
* A screen in an app. It is either an [ParentScreen] which lists its child screens to navigate to
|
||||
* them or a [ChildScreen] which shows some content.
|
||||
*/
|
||||
sealed class Screen(val identifier: String)
|
||||
|
||||
class ParentScreen(
|
||||
identifier: String,
|
||||
val children: Map<String, Screen>,
|
||||
) : Screen(identifier)
|
||||
|
||||
class ChildScreen(
|
||||
identifier: String,
|
||||
val content: @Composable (NavController) -> Unit,
|
||||
) : Screen(identifier)
|
||||
|
||||
/** Create the navigation graph for [screen]. */
|
||||
fun NavGraphBuilder.screen(screen: Screen, navController: NavController) {
|
||||
when (screen) {
|
||||
is ChildScreen -> composable(screen.identifier) { screen.content(navController) }
|
||||
is ParentScreen -> {
|
||||
val menuRoute = "${screen.identifier}_menu"
|
||||
navigation(startDestination = menuRoute, route = screen.identifier) {
|
||||
// The menu to navigate to one of the children screens.
|
||||
composable(menuRoute) { ScreenMenu(screen, navController) }
|
||||
|
||||
// The content of the child screens.
|
||||
screen.children.forEach { (_, child) -> screen(child, navController) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ScreenMenu(
|
||||
screen: ParentScreen,
|
||||
navController: NavController,
|
||||
) {
|
||||
LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
screen.children.forEach { (name, child) ->
|
||||
item {
|
||||
Surface(
|
||||
Modifier.fillMaxWidth(),
|
||||
color = MaterialTheme.colorScheme.secondaryContainer,
|
||||
shape = CircleShape,
|
||||
) {
|
||||
Column(
|
||||
Modifier.clickable { navController.navigate(child.identifier) }
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user