如何使用 JetPack Compose 在 LazyColumn 项目中单击导航到详细信息视图?

Kom*_*ito 7 android kotlin android-jetpack-navigation android-jetpack-compose

我正在尝试使用 JetPack Compose 创建一个应用程序(第一次),但导航时遇到一些问题。该应用程序有一个包含 3 个项目的底部栏,可导航到所选屏幕。

这是有效的,问题是当我尝试访问屏幕之一中的 LazyColumn 的项目之一时。我想导航到另一个屏幕(配置文件),其中显示所选项目的数据,但我找不到方法。无论我如何尝试,我总是得到这个“@Composable 调用只能在 @Composable 函数的上下文中发生”。

有人可以帮助我解释如何做吗?我想要的是了解如何以及为什么,而不仅仅是复制。

谢谢

主要活动

class MainActivity : ComponentActivity() {

    @ExperimentalFoundationApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        setContent {
            val systemUiController = rememberSystemUiController()

            SideEffect {
                systemUiController.setStatusBarColor(color = PrimaryDark)
            }
            AppTheme() {


                MainScreen()

            }

        }
    }

    @ExperimentalFoundationApi
    @Composable
    fun MainScreen() {
        val navController = rememberNavController()
        val navigationItems = listOf(Obras, Talleres, Ajustes)
        Scaffold(bottomBar = {
            BottomNavigationBar(
                navController = navController,
                items = navigationItems
            )
        }) {

            NavigationHost(navController)
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

导航主机.kt

@ExperimentalFoundationApi
@Composable
fun NavigationHost(navController: NavHostController) {


    NavHost(navController = navController, startDestination = Obras.route) {
        composable(Obras.route) {
            Pantalla1(navigateToProfile = { authorId ->
                navController.navigate("${Profile.route}/$authorId")
            })

        }
        composable(Talleres.route) {
            Pantalla2()
        }

        composable(Ajustes.route) {
            Pantalla3()
        }

        composable(
            Profile.route + "/{authorId}",
            arguments = listOf(navArgument("authorId") { type = NavType.StringType })
        ) { backStackEntry ->
            val authorId = backStackEntry.arguments!!.getString("authorId")!!
            Profile(authorId)
        }

    }
}

Run Code Online (Sandbox Code Playgroud)

Pantalla1.kt

typealias AuthorId = String

@ExperimentalCoroutinesApi
@Composable
fun Pantalla1(navigateToProfile: (AuthorId) -> Unit) {


    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(
                paddingValues = PaddingValues(

                    bottom = 50.dp
                )
            ),
    ) {

        AutoresInfo(navigateToProfile)
    }

}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun AutoresInfo(navigateToProfile: (AuthorId) -> Unit) {
    var autoresList by remember {
        mutableStateOf<List<Autor>?>(null)
    }

    JetFirestore(path = { collection("autores") },
        queryOnCollection = { orderBy("nombre", Query.Direction.ASCENDING) },

        onRealtimeCollectionFetch = { value, exception ->
            autoresList = value.getListOfObjects()
        }) {
        autoresList?.let {
            val grouped = it.groupBy { it.nombre[0] }
            LazyColumn(

                modifier = Modifier.fillMaxSize()

            ) {


                grouped.forEach { (initial, autoresForInitial) ->
                    stickyHeader {
                        StickyHeaderAutores(initial = initial.toString())
                    }

                    items(autoresForInitial, key = { autor -> autor.nombre }) { autor ->
                        Surface(modifier = Modifier.clickable { navigateToProfile(autor.nombre) }) {
                            @OptIn(coil.annotation.ExperimentalCoilApi::class)
                            AutorCard(autor)
                        }


                    }
                }


            }
        } ?: Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            CircularProgressIndicator(
                color = Color.Red,
                modifier = Modifier

                    .size(50.dp)

            )
        }

    }


}

Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 2

步骤 1. 将参数添加到您的个人资料导航路线。查看有关使用参数导航的文档

composable(
    Profile.route + "/{authorId}",
    arguments = listOf(navArgument("authorId") { type = NavType.StringType })
) { backStackEntry ->
    val authorId = backStackEntry.arguments!!.getString("authorId")!!
    Profile(authorId)
}
Run Code Online (Sandbox Code Playgroud)

步骤 2. 您需要navigateToProfile从您的NavigationHost. 如果不是,您可以替换AuthorId为(或其他类型) :IntString

typealias AuthorId = String

@Composable
fun NavigationHost(navController: NavHostController){
    NavHost(navController = navController, startDestination = Obras.route) {
        composable(Obras.route) {
            Pantalla1(navigateToProfile = { authorId ->
                navController.navigate("${Profile.route}/$authorId")
            })
        }
        ... 
}

@Composable
fun Pantalla1(navigateToProfile: (AuthorId) -> Unit) {
    ...
        AutoresInfo(navigateToProfile)
    ...
}

@Composable
fun AutoresInfo(navigateToProfile: (AuthorId) -> Unit) {
    ...
    items(autoresForInitial, key = { autor -> autor.nombre }) { autor ->
        Surface(modifier = Modifier.clickable {
            navigateToProfile(author.id)
        }) {
            AutorCard(autor)
        }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

步骤 3. 在您的配置文件可组合项中,您需要按 id 获取作者。不确定是什么JetFirestore,您可能应该使用它。

@Composable
fun Profile(id: AuthorId) {
    JetFirestore(
        // fetch author by id
    )
}
Run Code Online (Sandbox Code Playgroud)