英文:
How to call navigation from onStart activity in jetpack compose
问题
以下是您要翻译的部分:
我想要在用户已登录的情况下,从我的登录屏幕导航到主屏幕。由于我对Kotlin和Jetpack Compose还不熟悉,我不确定如何做到这一点,因为`SetContent{}`只能从`onCreate`方法中调用,而`Navigation()`组件只能从可组合部分内部调用。在Java+XML格式编码中,我们通常使用意图(Intents)和`StartActivity()`,但由于Jetpack Compose推荐单一活动和多屏幕编程风格,我不太理解这一点。
class MainActivity : ComponentActivity() {
//private lateinit var auth: FirebaseAuth
lateinit var mGoogleSignInClient: GoogleSignInClient
private lateinit var signInLauncher: ActivityResultLauncher<Intent>
override fun onStart() {
super.onStart()
// 检查用户是否已登录(非空),并相应地更新UI。
val account = GoogleSignIn.getLastSignedInAccount(this);
if (account != null) {
// 在XML风格中,我们曾经使用以下方式:
// Intent intent = new Intent(LoginActivity.this, UserHomeActivity.class);
// startActivity(intent);
account.getEmail()?.let { Log.d("已登录:", it) };
} else {
Log.d("已登录:", "未登录");
}
}
override fun onCreate(savedInstanceState: Bundle?) {
val gso =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build()
mGoogleSignInClient = GoogleSignIn.getClient(
this,
gso
)
signInLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
ActivityResultCallback<ActivityResult> { result ->
val task: Task<GoogleSignInAccount> =
GoogleSignIn.getSignedInAccountFromIntent(result.getData())
handleSignInResult(task)
})
super.onCreate(savedInstanceState)
setContent{
Navigation(mGoogleSignInClient = mGoogleSignInClient, signInLauncher = signInLauncher)
}
}
private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>
// ,navController: NavController
) {
try {
val account = completedTask.getResult(ApiException::class.java)
val idToken = account.idToken
// navController.navigate(Screens.UserHomeScreen.route)
// val intent = Intent(this@LoginActivity, UserHomeActivity::class.java)
// startActivity(intent)
} catch (e: ApiException) {
Log.w("登录错误", "signInResult:failed code=" + e.statusCode)
Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show()
}
}
}
英文:
I would like to navigate from my login screen to home screen in case the user is logged in. Being new to kotlin and jetpack compose, I'm not sure how this can be done since SetContent{}
should only be called from on create method and the Navigation() component can only be called from within a composable. Back in Java+XMl format coding we used to use intents and StartActivity(), but since jetpack compose recommends a single activity and multiple screen programming style, I don't understand this
class MainActivity : ComponentActivity() {
//private lateinit var auth: FirebaseAuth
lateinit var mGoogleSignInClient: GoogleSignInClient
private lateinit var signInLauncher: ActivityResultLauncher<Intent>
override fun onStart() {
super.onStart()
// Check if user is signed in (non-null) and update UI accordingly.
val account = GoogleSignIn.getLastSignedInAccount(this);
if (account != null) {
// in XML style , we used to use
// Intent intent = new Intent(LoginActivity.this, UserHomeActivity.class);
// startActivity(intent);
account.getEmail()?.let { Log.d("Signed In: ", it) };
} else {
Log.d("Signed In: ", "Not signed in");
}
}
override fun onCreate(savedInstanceState: Bundle?) {
val gso =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build()
mGoogleSignInClient = GoogleSignIn.getClient(
this,
gso
)
signInLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
ActivityResultCallback<ActivityResult> { result ->
val task: Task<GoogleSignInAccount> =
GoogleSignIn.getSignedInAccountFromIntent(result.getData())
handleSignInResult(task)
})
super.onCreate(savedInstanceState)
setContent{
Navigation(mGoogleSignInClient = mGoogleSignInClient, signInLauncher = signInLauncher)
}
private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>
// ,navController: NavController
) {
try {
val account = completedTask.getResult(ApiException::class.java)
val idToken = account.idToken
// navController.navigate(Screens.UserHomeScreen.route)
// val intent = Intent(this@LoginActivity, UserHomeActivity::class.java)
// startActivity(intent)
} catch (e: ApiException) {
Log.w("Sign In Error", "signInResult:failed code=" + e.statusCode)
Toast.makeText(this, "Sign in failed", Toast.LENGTH_SHORT).show()
}
}
答案1
得分: 1
在你的主活动中的 setContent {}
块中调用你的 NavHost()
函数。在你的 NavHost()
函数中,你的 startDestination
应该是你的登录屏幕。将你的登录逻辑移到 LoginScreen 可组合的函数中,类似于下面的示例:
override fun onCreate(savedInstanceState: Bundle?) {
NavigationHost(navController = rememberNavController())
}
@Composable
fun NavigationHost(navController: NavHostController) {
NavHost(
navController = navController,
startDestination = Screen.LoginScreen.route
) {
// 其他部分...
}
}
英文:
Call your NavHost()
function inside the setContent {}
block in your main activity. In your NavHost()
function your startDestination
should be your login screen. And move your login logic to the LoginScreen composable. Something similar to below:
override fun onCreate(savedInstanceState: Bundle?) {
NavigationHost(navController = rememberNavController())
}
and
@Composable
fun NavigationHost(navController: NavHostController) {
NavHost(
navController = navController,
startDestination = Screen.LoginScreen.route
) {
...
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论