我们如何比较JetPack组合中的TextField值相同的值?
我在Android JetPack组成的登录屏幕上,并且我有ScreenA和ScreenB,在ScreenA中,我有电子邮件,在ScreenB中,我再次有邮件并确认邮件,因此我想控制这三个电子邮件值相同的值。在ScreenA中,当我放任何邮件时,在ScreenB中,两个邮件都必须使用ScreenA,是否有其他解决方案?
screena:
@Composable
fun ScreenA(
navController: NavController,
model: MyViewModel
) {
val email = remember { mutableStateOf(TextFieldValue()) }
Column(
Modifier
.fillMaxSize()
,
horizontalAlignment = Alignment.CenterHorizontally
) {
val context = LocalContext.current
OutlinedTextField(
value = emailState.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = custom,
textColor = custom,
),
onValueChange = { emailState.value = it },
label = { Text(text = "Email") },
placeholder = { Text(text = "Email") },
singleLine = true,
modifier = Modifier.fillMaxWidth(0.8f)
)
}
屏幕B:
@Composable
fun ScreenB(
navController: NavController,
model: MyViewModel
) {
val emailState = remember { mutableStateOf(TextFieldValue()) }
val confirmEmailState = remember { mutableStateOf(TextFieldValue()) }
Column(
Modifier.fillMaxSize() ,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = emailState.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = custom,
textColor = custom,
),
onValueChange = { emailState.value = it },
label = { Text(text = "E-mail") },
singleLine = true,
modifier = Modifier.fillMaxWidth(0.8f)
)
OutlinedTextField(
value = confirmEmailState.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = custom,
textColor = custom,
),
onValueChange = { confirmEmailState.value = it },
label = { Text(text = "Confirm E-mail") },
placeholder = { Text(text = "Confirm E-mail") },
singleLine = true,
modifier = Modifier.fillMaxWidth(0.8f)
)
}
ViewModel:
@HiltViewModel
class MyViewModel @Inject constructor(
val db: FirebaseFirestore,
val auth: FirebaseAuth,
) : ViewModel() {
var singIn = mutableStateOf(false)
var isInProgress = mutableStateOf(false)
var popNotification = mutableStateOf<Event<String>?>(null)
var userData = mutableStateOf<User?>(null)
init {
val currentUser = auth.currentUser
singIn.value = currentUser != null
currentUser?.uid?.let { uid ->
getUserData(uid)
}
}
fun onSignOut() {
auth.signOut()
}
fun onSignUp(
email: String,
password: String
) {
if (
email.isEmpty()
) {
handledException(customMessage = "Please fill in all fields")
return
}
isInProgress.value = true
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
singIn.value = true
} else {
handledException(customMessage = "signed failed")
}
isInProgress.value = false
}
.addOnFailureListener {
}
}
fun onSignUpEmail(
emailState: String,
confirmEmailState: String,
) {
if (
emailState.isEmpty() or
confirmEmailState.isEmpty()
) {
handledException(customMessage = "Please fill in all fields")
return
}
isInProgress.value = true
db.collection(USERS).whereEqualTo("email", email.replace(" ", "")).get()
.addOnSuccessListener { documents ->
if (documents.size() > 0) {
handledException(customMessage = "mail already exist")
isInProgress.value = false
} else {
createOrUpdateProfile(
emailState = emailState,
confirmEmailState = confirmEmailState,
)
isInProgress.value = false
}
}
.addOnFailureListener { }
}
private fun createOrUpdateProfile(
emailState: String? = null,
confirmEmailState: String? = null,
) {
val uid = auth.currentUser?.uid
val userData = User(
emailState = emailState ?: userData.value?.emailState,
confirmEmailState = confirmEmailState ?: userData.value?.confirmEmailState,
)
uid?.let {
isInProgress.value = true
db.collection(USERS).document(uid).get()
.addOnSuccessListener {
if (it.exists()) {
it.reference.update(userData.toMap())
.addOnSuccessListener {
this.userData.value = userData
isInProgress.value = false
}
.addOnFailureListener {
handledException(customMessage = "Cannot Update user")
isInProgress.value = false
}
} else {
db.collection(USERS).document(uid).set(userData)
getUserData(uid)
isInProgress.value = false
}
}
.addOnFailureListener { exception ->
handledException(exception, "Cannot create user")
isInProgress.value = false
}
}
}
private fun getUserData(uid: String) {
isInProgress.value = true
db.collection(USERS).document(uid).get()
.addOnSuccessListener {
val user = it.toObject<User>()
userData.value = user
isInProgress.value = false
}
.addOnFailureListener { exception ->
handledException(exception, "Cannot retrieve user data")
isInProgress.value = false
}
}
fun onLogin(email: String, pass: String) {
if (email.isEmpty() or pass.isEmpty()) {
handledException(customMessage = "Please fill in all fields")
return
}
isInProgress.value = true
auth.signInWithEmailAndPassword(email, pass)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
singIn.value = true
isInProgress.value = false
auth.currentUser?.uid?.let { uid ->
// handledException(customMessage = "Login success")
getUserData(uid)
}
} else {
handledException(task.exception, "Login failed")
isInProgress.value = false
}
}
.addOnFailureListener { exc ->
handledException(exc, "Login failed")
isInProgress.value = false
}
}
private fun handledException(exception: Exception? = null, customMessage: String = "") {
exception?.printStackTrace()
val errorMsg = exception?.message ?: ""
val message = if (customMessage.isEmpty()) {
errorMsg
} else {
"$customMessage: $errorMsg"
}
popNotification.value = Event(message)
}
I have register screen in android jetpack compose, and I have ScreenA and ScreenB, in ScreenA I have email and in ScreenB I have again mail and confirm mail, so I want to control those three email values is same value. In ScreenA when I put any mail, in ScreenB both mail must be same mail with ScreenA, any solution?
ScreenA:
@Composable
fun ScreenA(
navController: NavController,
model: MyViewModel
) {
val email = remember { mutableStateOf(TextFieldValue()) }
Column(
Modifier
.fillMaxSize()
,
horizontalAlignment = Alignment.CenterHorizontally
) {
val context = LocalContext.current
OutlinedTextField(
value = emailState.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = custom,
textColor = custom,
),
onValueChange = { emailState.value = it },
label = { Text(text = "Email") },
placeholder = { Text(text = "Email") },
singleLine = true,
modifier = Modifier.fillMaxWidth(0.8f)
)
}
ScreenB:
@Composable
fun ScreenB(
navController: NavController,
model: MyViewModel
) {
val emailState = remember { mutableStateOf(TextFieldValue()) }
val confirmEmailState = remember { mutableStateOf(TextFieldValue()) }
Column(
Modifier.fillMaxSize() ,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
OutlinedTextField(
value = emailState.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = custom,
textColor = custom,
),
onValueChange = { emailState.value = it },
label = { Text(text = "E-mail") },
singleLine = true,
modifier = Modifier.fillMaxWidth(0.8f)
)
OutlinedTextField(
value = confirmEmailState.value,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = white,
focusedIndicatorColor = Grey,
unfocusedIndicatorColor = Grey,
focusedLabelColor = Grey,
unfocusedLabelColor = Grey,
cursorColor = custom,
textColor = custom,
),
onValueChange = { confirmEmailState.value = it },
label = { Text(text = "Confirm E-mail") },
placeholder = { Text(text = "Confirm E-mail") },
singleLine = true,
modifier = Modifier.fillMaxWidth(0.8f)
)
}
viewmodel:
@HiltViewModel
class MyViewModel @Inject constructor(
val db: FirebaseFirestore,
val auth: FirebaseAuth,
) : ViewModel() {
var singIn = mutableStateOf(false)
var isInProgress = mutableStateOf(false)
var popNotification = mutableStateOf<Event<String>?>(null)
var userData = mutableStateOf<User?>(null)
init {
val currentUser = auth.currentUser
singIn.value = currentUser != null
currentUser?.uid?.let { uid ->
getUserData(uid)
}
}
fun onSignOut() {
auth.signOut()
}
fun onSignUp(
email: String,
password: String
) {
if (
email.isEmpty()
) {
handledException(customMessage = "Please fill in all fields")
return
}
isInProgress.value = true
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
singIn.value = true
} else {
handledException(customMessage = "signed failed")
}
isInProgress.value = false
}
.addOnFailureListener {
}
}
fun onSignUpEmail(
emailState: String,
confirmEmailState: String,
) {
if (
emailState.isEmpty() or
confirmEmailState.isEmpty()
) {
handledException(customMessage = "Please fill in all fields")
return
}
isInProgress.value = true
db.collection(USERS).whereEqualTo("email", email.replace(" ", "")).get()
.addOnSuccessListener { documents ->
if (documents.size() > 0) {
handledException(customMessage = "mail already exist")
isInProgress.value = false
} else {
createOrUpdateProfile(
emailState = emailState,
confirmEmailState = confirmEmailState,
)
isInProgress.value = false
}
}
.addOnFailureListener { }
}
private fun createOrUpdateProfile(
emailState: String? = null,
confirmEmailState: String? = null,
) {
val uid = auth.currentUser?.uid
val userData = User(
emailState = emailState ?: userData.value?.emailState,
confirmEmailState = confirmEmailState ?: userData.value?.confirmEmailState,
)
uid?.let {
isInProgress.value = true
db.collection(USERS).document(uid).get()
.addOnSuccessListener {
if (it.exists()) {
it.reference.update(userData.toMap())
.addOnSuccessListener {
this.userData.value = userData
isInProgress.value = false
}
.addOnFailureListener {
handledException(customMessage = "Cannot Update user")
isInProgress.value = false
}
} else {
db.collection(USERS).document(uid).set(userData)
getUserData(uid)
isInProgress.value = false
}
}
.addOnFailureListener { exception ->
handledException(exception, "Cannot create user")
isInProgress.value = false
}
}
}
private fun getUserData(uid: String) {
isInProgress.value = true
db.collection(USERS).document(uid).get()
.addOnSuccessListener {
val user = it.toObject<User>()
userData.value = user
isInProgress.value = false
}
.addOnFailureListener { exception ->
handledException(exception, "Cannot retrieve user data")
isInProgress.value = false
}
}
fun onLogin(email: String, pass: String) {
if (email.isEmpty() or pass.isEmpty()) {
handledException(customMessage = "Please fill in all fields")
return
}
isInProgress.value = true
auth.signInWithEmailAndPassword(email, pass)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
singIn.value = true
isInProgress.value = false
auth.currentUser?.uid?.let { uid ->
// handledException(customMessage = "Login success")
getUserData(uid)
}
} else {
handledException(task.exception, "Login failed")
isInProgress.value = false
}
}
.addOnFailureListener { exc ->
handledException(exc, "Login failed")
isInProgress.value = false
}
}
private fun handledException(exception: Exception? = null, customMessage: String = "") {
exception?.printStackTrace()
val errorMsg = exception?.message ?: ""
val message = if (customMessage.isEmpty()) {
errorMsg
} else {
"$customMessage: $errorMsg"
}
popNotification.value = Event(message)
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将电子邮件状态移至您的ViewModel。您也可以将其转换为流,但不是必须的。
在您的ViewModel中看起来好像:
Move emailState to your viewModel. You can also convert it to Flow, but it is not obligatory.
It looks like that in your viewmodel: