当我们使用 XML 和 Kotlin 设置时,使用带有电子邮件和密码设置的 edittext 会自动显示选项来填充键盘建议中的详细信息,但在 Compose 架构中不会发生同样的情况。
他们是否提供了一种方法来做到这一点,或者这是目前的一个缺点?
我知道我们可以将其构建为 XML 并将其放入可组合项中,但这不是一种干净的方式,因此如果有任何适当的解决方案,请提供帮助
是的,确实存在正确的解决方案,如下所述。
使用 Google Credential Manager 保存用户凭据
首先您需要以下依赖项
androidx.credentials:凭证:1.2.2
这是我处理该函数的自定义构建类
import android.app.Activity
import androidx.credentials.CreatePasswordRequest
import androidx.credentials.CredentialManager
import androidx.credentials.GetCredentialRequest
import androidx.credentials.GetPasswordOption
import androidx.credentials.PasswordCredential
import androidx.credentials.exceptions.CreateCredentialCancellationException
import androidx.credentials.exceptions.CreateCredentialException
import androidx.credentials.exceptions.GetCredentialCancellationException
import androidx.credentials.exceptions.GetCredentialException
import androidx.credentials.exceptions.NoCredentialException
class AccountManager(val activity: Activity) {
private val credentialManager = CredentialManager.create(activity)
suspend fun signUp(username: String, password: String): SignupResult {
return try {
credentialManager.createCredential(activity, CreatePasswordRequest(username, password))
SignupResult.Success(username)
} catch (e: CreateCredentialCancellationException) {
e.printStackTrace()
SignupResult.Cancelled
} catch (e: CreateCredentialException) {
SignupResult.Failure
} catch (e:Exception){
SignupResult.Failure
}
}
suspend fun signIn():SignInResult{
return try {
val res = credentialManager.getCredential(activity,GetCredentialRequest(listOf(GetPasswordOption())))
val credential = res.credential as? PasswordCredential ?: return SignInResult.Failure
SignInResult.Success(credential.id,credential.password)
} catch (e: GetCredentialCancellationException) {
e.printStackTrace()
SignInResult.Cancelled
} catch (e: NoCredentialException) {
SignInResult.NoCredentials
} catch (e: GetCredentialException) {
SignInResult.Failure
} catch (e:Exception){
SignInResult.Failure
}
}
}
sealed interface SignInResult {
data class Success(val username: String,val pwd: String) : SignInResult
data object Cancelled : SignInResult
data object Failure : SignInResult
data object NoCredentials : SignInResult
}
sealed interface SignupResult {
data class Success(val username: String) : SignupResult
data object Cancelled : SignupResult
data object Failure : SignupResult
}
这里我还提到了导入以便于实现
下面是您的可组合项的代码
val context = LocalContext.current
val scope = rememberCoroutineScope()
val accountManager = remember {
AccountManager(context as ComponentActivity)
}
//submit the user entered email password to our custom class to save it
Text ("Login", modifier = Modifier.clickable {
scope.launch {
accountManager.signUp(email,password)
}
})
//When the screen is opened use below code to show user the prompt to fetch the details also errors can be handled specifically
LaunchedEffect(key1 = true) {
when (val res = accountManager.signIn()) {
SignInResult.Cancelled -> {}
SignInResult.Failure -> {}
SignInResult.NoCredentials -> {}
is SignInResult.Success -> {
//Update the field with this object
res.username
res.pwd
}
}
}