你的 App 里有没有让用户填表单的地方?比如注册、登录、填写地址之类的。
我最近发现一个特别能提升用户体验的地方 —— 自动填充,这个功能可以大大提升用户体验。
于是我调查了一下,发现在 Compose 中 实现起来超简单,只需要几行代码。
来,五分钟,搞定自动填充!
什么是自动填充
稍等,我先介绍一下,什么是自动填充?
简单来说,自动填充就是让系统帮你"记住"一些常用信息,下次需要填写时自动填进去。比如你的姓名、地址、邮箱、密码这些,就不用每次都手动打了。
Android 上有很多自动填充服务可以用,大多数是密码管理器。
Google 自带的服务除了管理密码,还能记住你的账户信息。你可以在手机设置里找到自动填充选项——在 Pixel 手机上,这个设置叫"密码、通行密钥和账户"。
记得要把服务设为默认,自动填充才能生效。
当然了,对于国产手机,可能不是这个了,此处我就以小米手机为例,在小米手机中,这个功能叫“智能密码管理”。
Compose 中的自动填充
Compose 以前有个 Autofill API,不过在 Compose 1.8.0 版本已经不推荐用了。现在推荐用基于语义的新 API 来实现自动填充。
支持的数据类型
自动填充能识别很多种信息,常用的有这些:
- 地址相关
- 街道(
AddressStreet) - 地区(
AddressRegion) - 国家(
AddressCountry)
- 街道(
- 姓名相关
- 全名(
PersonFullName) - 名字(
PersonFirstName) - 姓氏(
PersonLastName)
- 全名(
- 登录相关
- 新用户名(
NewUsername) - 用户名(
Username) - 新密码(
NewPassword) - 密码(
Password)
- 新用户名(
完整列表可以看官方文档,这里不再赘述。
其实还有另一个原因不想赘述,往下看!
实现自动填充
实现特别简单,只需要在 semantics 修饰符里设置 contentType 就行:
TextField(
...
modifier = Modifier
.semantics {
contentType = ContentType.Username
}
)
举个例子,假设你要做一个收集用户姓名的表单:
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
SectionTitle("Sign in")
AutofillTextField(
value = username,
onValueChange = { username = it },
label = "Username or email",
contentType = ContentType.Username,
keyboardType = KeyboardType.Email,
)
AutofillTextField(
value = password,
onValueChange = { password = it },
label = "Password",
contentType = ContentType.Password,
keyboardType = KeyboardType.Password,
visualTransformation = PasswordVisualTransformation(),
)
}
此处的 AutofillTextField 是一个自定义的控件实现,防止编写重复代码:
@Composable
private fun AutofillTextField(
value: String,
onValueChange: (String) -> Unit,
label: String,
contentType: ContentType,
modifier: Modifier = Modifier,
keyboardType: KeyboardType = KeyboardType.Text,
visualTransformation: VisualTransformation = VisualTransformation.None,
) {
OutlinedTextField(
value = value,
onValueChange = onValueChange,
label = { Text(label) },
keyboardOptions = KeyboardOptions(keyboardType = keyboardType),
singleLine = true,
visualTransformation = visualTransformation,
modifier = modifier
.fillMaxWidth()
.semantics {
this.contentType = contentType
},
)
}
在设备上的效果如下所示:
保存数据
用户填完信息后,还得让他们能保存下来,下次才能自动填充。
此处,我们需要进行手动保存。
一般情况下,我们会有一个“登录”按钮,当触发登录按钮的时候,我们可以进行保存操作。
代码上,需要借助 AutofillManager 来手动触发:
val autofillManager = LocalAutofillManager.current
然后在按钮点击时调用 commit 方法:
Column(...) {
// Text fields
Button(
onClick = {
autofillManager?.commit()
},
modifier = Modifier.fillMaxWidth(),
) {
Text("Login")
}
}
好的,所有代码都准备完毕,我们直接看看效果:
中途因为录屏保护,黑屏了一段时间,不过无伤大雅。
体验提升
自动填充能减少打错字的情况。像密码这种信息,直接填进去就行,不用担心打错。
还有就是赶时间的时候,比如抢票,自动填充能帮你快速填完信息。
而且,自动填充对很多人都有帮助。比如,有些人手部活动不太方便,或者容易手抖,又或者冬天手冷僵硬的时候,打字对他们来说挺费劲的。有了自动填充,他们就不用费力打字了。
反正对我来讲,自动填充可以一键填充用户名密码,省掉了很多手动输入的时间!
一点小提醒
如果你去看官方文档,你会发现自动填充支持那么多属性,但实际上,Android Autofill 只是系统框架,真正能填什么取决于你手机当前启用的 Autofill provider,比如 Google Password Manager、厂商密码管家、或者小米的智能密码管理等。
很多 provider 主要只支持:
UsernamePasswordNewUsernameNewPassword
不一定支持:
EmailAddress- 姓名
- 地址
- 电话
- 个人资料类字段
所以你的 Compose 代码里即使写了:
contentType = ContentType.PersonFirstName
//
contentType = ContentType.AddressStreet
系统也可能识别到了字段,但当前 provider 没有可用数据集,那么就不可用。