jetpack compose 中自动填充电子邮件密码 - Android

问题描述 投票:0回答:1

当我们使用 XML 和 Kotlin 设置时,使用带有电子邮件和密码设置的 edittext 会自动显示选项来填充键盘建议中的详细信息,但在 Compose 架构中不会发生同样的情况。

他们是否提供了一种方法来做到这一点,或者这是目前的一个缺点?

我知道我们可以将其构建为 XML 并将其放入可组合项中,但这不是一种干净的方式,因此如果有任何适当的解决方案,请提供帮助

android kotlin android-jetpack-compose autofill
1个回答
5
投票

是的,确实存在正确的解决方案,如下所述。

使用 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
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.