首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >调用只能从@composable函数的上下文中使用组合导航进行

调用只能从@composable函数的上下文中使用组合导航进行
EN

Stack Overflow用户
提问于 2022-10-24 12:38:41
回答 3查看 146关注 0票数 3

嗨,由于Jetpack Compose的缘故,我现在很难在@composable invocations can only happen from the context of an @composable function中导航。我有一个功能:

代码语言:javascript
运行
复制
private fun signInResult(result: FirebaseAuthUIAuthenticationResult) {
        val response = result.idpResponse
        if (result.resultCode == RESULT_OK) {
            user = FirebaseAuth.getInstance().currentUser
            Log.e("MainActivity.kt", "Innlogging vellykket")
            ScreenMain()
        } else {
            Log.e("MainActivity.kt", "Feil med innlogging" + response?.error?.errorCode)
        }
    }

和下面显示的导航类一起使用,我只得到上面显示的错误消息,如何修复它?

代码语言:javascript
运行
复制
@Composable
         fun ScreenMain(){
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = Routes.Vareliste.route) {

        composable(Routes.SignUp.route) {
            SignUp(navController = navController)
        }

        composable(Routes.ForgotPassword.route) { navBackStack ->
            ForgotPassword(navController = navController)
        }

        composable(Routes.Vareliste.route) { navBackStack ->
           Vareliste(navController = navController)
       }

       composable(Routes.Handlekurv.route) { navBackStack ->
            Handlekurv(navController = navController)
        }
        
        composable(Routes.Profileromoss.route) { navBackStack ->
            Profileromoss(navController = navController)
        }

   }
}

用完整的代码编辑,如果你们想看的话,这是全班的全部代码!

代码语言:javascript
运行
复制
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        JetpackComposeDemoTheme {
             Surface(
                     modifier = Modifier.fillMaxSize(),
                      color = MaterialTheme.colors.background
                            ) {
                LoginPage()
            }
        }
    }
}

private var user: FirebaseUser? = FirebaseAuth.getInstance().currentUser
private lateinit var auth: FirebaseAuth



@Composable
fun LoginPage() {
    Box(modifier = Modifier.fillMaxSize()) {
    }
    Column(
        modifier = Modifier.padding(20.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        Text(text = "Velkommen til ITGuys", style = TextStyle(fontSize = 36.sp))

        Spacer(modifier = Modifier.height(20.dp))
        Box(modifier = Modifier.padding(40.dp, 0.dp, 40.dp, 0.dp)) {
            Button(
                onClick = { signIn() },
                shape = RoundedCornerShape(50.dp),
                modifier = Modifier
                    .fillMaxWidth()
                    .height(50.dp)
            ) {
                Text(text = "Logg inn")
            }
        }
    }
}

private fun signIn() {
    val providers = arrayListOf(
        AuthUI.IdpConfig.EmailBuilder().build(),
        AuthUI.IdpConfig.GoogleBuilder().build()
    )
    val signinIntent = AuthUI.getInstance()
    .createSignInIntentBuilder()
    .setAvailableProviders(providers)
    .build()

    signInLauncher.launch(signinIntent)
}



private val signInLauncher = registerForActivityResult(
    FirebaseAuthUIActivityResultContract()
) {
    res -> this.signInResult(res)
}

private fun signInResult(result: FirebaseAuthUIAuthenticationResult) {
    val response = result.idpResponse
    if (result.resultCode == RESULT_OK) {
        user = FirebaseAuth.getInstance().currentUser
        Log.e("MainActivity.kt", "Innlogging vellykket")
        ScreenMain()
    } else {
        Log.e("MainActivity.kt", "Feil med innlogging" + response?.error?.errorCode)
    }
}

}

我需要添加更多的文本,以允许张贴这么多的代码,你可以忽略这个文本,因为它只是为了能够张贴。

EN

Stack Overflow用户

发布于 2022-10-25 15:53:24

那么,在您的MainActivity中,您希望导航组件位于顶部:

代码语言:javascript
运行
复制
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        JetpackComposeDemoTheme {
             Surface(
                     modifier = Modifier.fillMaxSize(),
                      color = MaterialTheme.colors.background
                            ) {
                ScreenMain()
            }
        }
    }
}

然后为登录页面添加一条路由到您的导航主机:

代码语言:javascript
运行
复制
composable(Routes.LoginPage.route) {
            LoginPage(navController = navController)
        }

我认为这是一个很大的变化,但是您必须依靠视图模型来进行身份验证,这样它就可以处理调用,而不是阻塞ui或显示加载屏幕,并与视图进行通信。

看起来会是这样的:

代码语言:javascript
运行
复制
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    val viewModel = MyViewModel()

    setContent {
        JetpackComposeDemoTheme {
             Surface(
                     modifier = Modifier.fillMaxSize(),
                      color = MaterialTheme.colors.background
                            ) {
                ScreenMain(viewModel)
            }
        }
    }

}

在LoginPage中,您希望访问视图模型来启动auth服务调用。

在LoginPage中,您希望访问视图模型来观察调用是否成功,在这种情况下执行导航

在MyViewModel中,您希望有身份验证调用,如果auth已满,则更新触发导航的变量。

以下是撰写中的一个示例防火墙身份验证应用程序的示例,我将使用它作为指南https://firebase.blog/posts/2022/05/adding-firebase-auth-to-jetpack-compose-app

票数 0
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74181211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档