Jetpack Compose Fragment onCreate 问题
JetpackCompose Fragment onCreate issue
我需要在我的 SignScreen 的 onCreate 方法中调用一个函数,但没有任何适用的地方。我无法从任何地方调用 currentUserCheck
函数。
我尝试了什么:
在 viewModel 的 init
块中调用它。但问题是它在这里为 NavController
抛出 nullPointerException
。
在 MainActivity
和 MyTheme
中调用它,但我在这些范围内遇到了很多奇怪的问题。
ViewModel:
@HiltViewModel
class SignViewModel (@ApplicationContext context: Context) : ViewModel() {
val auth = FirebaseAuth.getInstance()
init {
currentUserCheck(NavController(context))
}
fun signIn(email: String?, password: String?, context: Context, navController: NavController) {
if (email != null && email.isNotBlank() && password != null && password.isNotBlank()) {
auth.signInWithEmailAndPassword(email, password).addOnSuccessListener {
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.SigningScreen.route) {
inclusive = true
}
}
}.addOnFailureListener {
Toast.makeText(context, it.localizedMessage, Toast.LENGTH_LONG).show()
}
} else {
Toast.makeText(
context,
"Lütfen email ve şifre alanlarını boş bırakmayınız.",
Toast.LENGTH_LONG
).show()
}
}
fun signUp(email: String?, password: String?, context: Context, navController: NavController) {
if (email != null && email.isNotBlank() && password != null && password.isNotBlank()) {
auth.createUserWithEmailAndPassword(email, password)
.addOnSuccessListener {
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.ProfileScreen.route) {
inclusive = true
}
}
}
} else {
Toast.makeText(
context,
"Lütfen email ve şifre alanlarını boş bırakmayınız.",
Toast.LENGTH_LONG
).show()
}
}
fun currentUserCheck(navController: NavController) {
if (auth.currentUser != null) {
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.ProfileScreen.route) {
inclusive = true
}
}
}
}
}
解决方案
正如@Pztar 所说,我将身份验证控制操作声明为 viewModel 中的一个状态,然后我在我的 Composable SignScreen
中使用 LaunchEffect 观察到它并解决了。
@HiltViewModel
class SignViewModel (@ApplicationContext context: Context) : ViewModel() {
val auth = FirebaseAuth.getInstance()
var currentUser = mutableStateOf(false)
//New currenUserCheck method that declare if state is true or not
fun currentUserCheck() {
if (auth.currentUser != null) {
currentUser.value = true
}
}
}
@Composable
fun SignScreen(viewModel: SignViewModel= hiltViewModel(),navController: NavController,context: Context) {
//Observing the state from my composable and routing user if state is true.
LaunchedEffect(key1 = Unit ){
viewModel.currentUserCheck()
if (viewModel.currentUser.value){
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.SigningScreen.route) {
inclusive = true
}
}
}
}
}
我需要在我的 SignScreen 的 onCreate 方法中调用一个函数,但没有任何适用的地方。我无法从任何地方调用 currentUserCheck
函数。
我尝试了什么:
在 viewModel 的
init
块中调用它。但问题是它在这里为NavController
抛出nullPointerException
。在
MainActivity
和MyTheme
中调用它,但我在这些范围内遇到了很多奇怪的问题。
ViewModel:
@HiltViewModel
class SignViewModel (@ApplicationContext context: Context) : ViewModel() {
val auth = FirebaseAuth.getInstance()
init {
currentUserCheck(NavController(context))
}
fun signIn(email: String?, password: String?, context: Context, navController: NavController) {
if (email != null && email.isNotBlank() && password != null && password.isNotBlank()) {
auth.signInWithEmailAndPassword(email, password).addOnSuccessListener {
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.SigningScreen.route) {
inclusive = true
}
}
}.addOnFailureListener {
Toast.makeText(context, it.localizedMessage, Toast.LENGTH_LONG).show()
}
} else {
Toast.makeText(
context,
"Lütfen email ve şifre alanlarını boş bırakmayınız.",
Toast.LENGTH_LONG
).show()
}
}
fun signUp(email: String?, password: String?, context: Context, navController: NavController) {
if (email != null && email.isNotBlank() && password != null && password.isNotBlank()) {
auth.createUserWithEmailAndPassword(email, password)
.addOnSuccessListener {
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.ProfileScreen.route) {
inclusive = true
}
}
}
} else {
Toast.makeText(
context,
"Lütfen email ve şifre alanlarını boş bırakmayınız.",
Toast.LENGTH_LONG
).show()
}
}
fun currentUserCheck(navController: NavController) {
if (auth.currentUser != null) {
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.ProfileScreen.route) {
inclusive = true
}
}
}
}
}
解决方案
正如@Pztar 所说,我将身份验证控制操作声明为 viewModel 中的一个状态,然后我在我的 Composable SignScreen
中使用 LaunchEffect 观察到它并解决了。
@HiltViewModel
class SignViewModel (@ApplicationContext context: Context) : ViewModel() {
val auth = FirebaseAuth.getInstance()
var currentUser = mutableStateOf(false)
//New currenUserCheck method that declare if state is true or not
fun currentUserCheck() {
if (auth.currentUser != null) {
currentUser.value = true
}
}
}
@Composable
fun SignScreen(viewModel: SignViewModel= hiltViewModel(),navController: NavController,context: Context) {
//Observing the state from my composable and routing user if state is true.
LaunchedEffect(key1 = Unit ){
viewModel.currentUserCheck()
if (viewModel.currentUser.value){
navController.navigate(ScreenHolder.ProfileScreen.route) {
popUpTo(ScreenHolder.SigningScreen.route) {
inclusive = true
}
}
}
}
}