You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Android Jetpack NavController导航至第三方组件?

Great question! When working with third-party library activities (like Firebase Auth UI, which requires an Intent built via its own builder and returns a result), you can absolutely replace startActivityForResult with NavController by combining it with the modern Activity Result API. Here's a step-by-step implementation:

1. Replace onActivityResult with ActivityResultLauncher

First, we'll ditch the deprecated onActivityResult method and register a launcher to handle the sign-in result. This integrates cleanly with Navigation's flow:

// In your main activity (or the activity hosting your NavHostFragment)
private val signInLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    val navController = findNavController(R.id.nav_host_fragment)
    
    if (result.resultCode == Activity.RESULT_OK) {
        // Successfully signed in
        val user = FirebaseAuth.getInstance().currentUser
        // Navigate to your app's main content (replace with your destination ID)
        navController.navigate(R.id.action_to_home_fragment)
    } else {
        val response = IdpResponse.fromResultIntent(result.data)
        when {
            response == null -> {
                // User canceled the sign-in flow
                Toast.makeText(this, "Sign-in canceled", Toast.LENGTH_SHORT).show()
            }
            else -> {
                // Handle sign-in errors (e.g., invalid credentials)
                val errorCode = response.error?.errorCode
                Toast.makeText(this, "Sign-in failed: $errorCode", Toast.LENGTH_SHORT).show()
            }
        }
        // Optionally navigate back to the starting destination
        navController.popBackStack()
    }
}

2. Trigger the Sign-In Flow with NavController Context

Instead of calling startActivityForResult directly, you'll build the Firebase Auth UI Intent as before, then launch it via the registered launcher. You can trigger this from a Fragment or ViewModel that has access to the NavController:

// In your Fragment/ViewModel
fun launchSignInFlow() {
    val providers = arrayListOf(
        AuthUI.IdpConfig.EmailBuilder().build(),
        AuthUI.IdpConfig.GoogleBuilder().build()
        // Add other providers as needed
    )

    val signInIntent = AuthUI.getInstance()
        .createSignInIntentBuilder()
        .setAvailableProviders(providers)
        .build()

    // Launch the sign-in activity
    signInLauncher.launch(signInIntent)
}

3. (Optional) Integrate with Navigation Graph Actions

If you want to formalize this flow in your navigation graph, you can define an action and use NavController to trigger it (though the launcher will still handle the actual Intent launch):

In your navigation.xml:

<fragment
    android:id="@+id/welcome_fragment"
    android:name="com.example.WelcomeFragment">
    <action
        android:id="@+id/action_welcome_to_sign_in"
        app:popUpTo="@id/welcome_fragment"
        app:popUpToInclusive="true"/>
</fragment>

Then in your Fragment:

findNavController().navigate(R.id.action_welcome_to_sign_in)
// Then call launchSignInFlow() in the destination's onCreateView or similar

This approach keeps your navigation logic centralized with NavController, while properly handling the third-party activity's result via the modern Activity Result API. No more managing request codes or messy onActivityResult overrides!

内容的提问来源于stack exchange,提问作者Zbigniew Malinowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:55:22