如何使用 Jetpack Compose 从单个目的地导航到多个目的地

Edw*_*win 1 android kotlin android-jetpack-navigation android-jetpack-compose jetpack-compose-navigation

总之,我想根据单击的项目导航到目的地。

在此输入图像描述

但问题是我创建这些项目的方式,这是我不知道如何隔离项目并为它们提供 onClick 函数的方式。

附言。我使用数据类和对象函数来制作项目;

data class MenuData(
    Val id: Int,
    Val title: String,
    val menuImageId: Int = 0
)
Run Code Online (Sandbox Code Playgroud)
object MenuModel {

    .....

    fun menuModelList(context: Context) = listOf(

        MenuData(
            id = 1,
            title = context.getString(R.string.menu_log),
            description = context.getString(R.string.menu_logText),
            menuImageId = R.drawable.menu_log
        ),
      .....
    )
}
Run Code Online (Sandbox Code Playgroud)


通常我所做的导航是(示例代码):

@Composable
fun WaysCard(
    waysInfo: WaysData,
    onWaysCardClick: (Int) -> Unit,
    modifier: Modifier = Modifier
) {
    Surface(
        shape = MaterialTheme.shapes.small,
        elevation = 10.dp,
        modifier = modifier
            .clickable { onWaysCardClick(waysInfo.id) }
    ) 
    ....
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我为可组合项提供了一个单击函数,并将数据类作为参数传递,因为通常这些项目是通用的,它们的大部分内容都以类似的方式排列。在这方面我现在正在尝试做。无论如何,内容都不相似。所以我为每个项目创建了目的地。所以我想从导航到这些预定义的目的地MenuScreen.Kt

我不知道将什么传递给 onClick 函数来导航到这些目的地。或者我是否应该像以前那样写它。

代码如下(MenuScreen.Kt):

@Composable
fun MenuCard(
    menuInfo: MenuData,
    onMenuCardClick: (Int) -> Unit,
    modifier: Modifier = Modifier
) {
    Surface(
        shape = MaterialTheme.shapes.small,
        elevation = 4.dp,
        modifier = modifier
            .clickable {  }
    ) {
        ....
    }
}
Run Code Online (Sandbox Code Playgroud)

为了便于理解,我们调用预定义的目的地;LogScreen.ktToDoScreen.ktLessonsScreen.ktContactScreen.kt

我不知道您是否需要更多信息,如果需要的话,我很乐意提供。

我真诚地感谢您提供的任何帮助。提前感谢您。

Vah*_*usi 5

如果我正确理解了这些问题,我有一个解决方案给你,我不知道它对你有多大作用

但如果您有不明白的地方,请询问,我很乐意指导您

请按照我说的做并查看输出。如果它符合您的需求,请发表评论告诉我,我会给您完整的解释

1 - 使用你想要的名称创建一个 Kotlin 文件 - 我将其命名为 Navigation

2 - 将附件中包含的所有代码放入该文件中


import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.navigation
import androidx.navigation.compose.rememberNavController

sealed class Screen(val route: String) {
    object Menu : Screen("menu")
}

sealed class LeafScreen(
    private val route: String
) {
    fun createRoute(root: Screen) = "${root.route}/$route"

    object Menu : LeafScreen("menu")
    object Lessons : LeafScreen("lessons")
    object Log : LeafScreen("log")
    object ToDo : LeafScreen("todo")
    object Contact : LeafScreen("contact")
}


@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = Screen.Menu.route
    ) {
        navigation(
            route = Screen.Menu.route,
            startDestination = LeafScreen.Menu.createRoute(Screen.Menu)
        ) {
            composable(
                LeafScreen.Menu.createRoute(Screen.Menu)
            ) {
                MenuScreen(
                    navigateToScreen = {
                        when (it) {
                            1 -> navController.navigate(LeafScreen.Log.createRoute(Screen.Menu))
                            2 -> navController.navigate(LeafScreen.Lessons.createRoute(Screen.Menu))
                            3 -> navController.navigate(LeafScreen.Contact.createRoute(Screen.Menu))
                            4 -> navController.navigate(LeafScreen.ToDo.createRoute(Screen.Menu))
                        }
                    }
                )
            }
            composable(
                LeafScreen.Lessons.createRoute(Screen.Menu)
            ) {
                LessonsScreen()
            }
            composable(
                LeafScreen.Log.createRoute(Screen.Menu)
            ) {
                LogScreen()
            }
            composable(
                LeafScreen.ToDo.createRoute(Screen.Menu)
            ) {
                ToDoScreen()
            }
            composable(
                LeafScreen.Contact.createRoute(Screen.Menu)
            ) {
                ContactScreen()
            }
        }
    }
}

@Composable
fun ContactScreen() {
    Box(Modifier.fillMaxSize()) {
        Text(text = "ContactScreen", modifier = Modifier.align(Alignment.Center))
    }
}

@Composable
fun ToDoScreen() {
    Box(Modifier.fillMaxSize()) {
        Text(text = "ToDoScreen", modifier = Modifier.align(Alignment.Center))
    }
}

@Composable
fun LogScreen() {
    Box(Modifier.fillMaxSize()) {
        Text(text = "LogScreen", modifier = Modifier.align(Alignment.Center))
    }
}

@Composable
fun LessonsScreen() {
    Box(Modifier.fillMaxSize()) {
        Text(text = "LessonsScreen", modifier = Modifier.align(Alignment.Center))
    }
}

data class MenuData(
    val id: Int,
    val title: String,
    val menuImageId: Int = 0
)

data class MenuViewState(
    val menus: List<MenuData> = arrayListOf<MenuData>().apply {
        add(MenuData(id = 1, title = "log", 0))
        add(MenuData(id = 2, title = "lessons", 0))
        add(MenuData(id = 3, title = "contacts", 0))
        add(MenuData(id = 4, title = "todo", 0))
    }
)

@Composable
fun MenuScreen(
    navigateToScreen: (Int) -> Unit
) {
    val uiState by remember {
        mutableStateOf(MenuViewState())
    }
    LazyColumn(

Run Code Online (Sandbox Code Playgroud)

3 - 最后,将可组合导航放入 MainActivity.kt 中

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import stackoverflow.answers.ui.theme.StackOverflowAnswersTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            StackOverflowAnswersTheme {
                AppNavigation()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)