在Android中使用数据绑定、Regex和Material进行表单验证
当构建一个需要用户提交信息的应用程序时,你需要在将这些数据发送到你的应用程序之前对其进行验证。这就是表单验证的概念所在。
当用户填写电子邮件时,应用程序应该能够检查用户是否提供了一个电子邮件输入。如果没有,就相应地通知用户填写正确的电子邮件格式。应用程序需要从用户那里获得许多数值和具体数据。本指南旨在帮助你了解如何使用Android studio实现这些概念。
前提条件
要开始学习本教程,请确保你具备以下要件。
- 确保你的电脑上安装了Android Studio。
- 对用android studio运行Kotlin的基本了解。
- 对使用Android材料设计库的基本了解。
设置一个安卓项目
为了开始,继续创建一个新的Android Studio项目,并有一个空的活动。确保你选择Kotlin作为你想运行应用程序的语言。

我们将使用Android材质设计库来设置基本的Android表单。因此,你需要让你的项目能够访问这个库。进入你的build.gradle 文件,在dependencies {} 内添加以下库。
implementation 'com.google.android.material:material:1.5.0'
一旦你添加了这个库,Sync 你的项目就可以下载并使这个库可以在你的项目中使用。
创建并添加基本的验证到一个材料表单中
Android材质设计帮助你建立一套交互式的、一致的原则设计。它有许多组件,可以让你实现你最大的设计潜力。
Material拥有必要的组件,允许你创建任何Android表单,同时确保整个应用程序的一致性。我们将创建一个基本的登录材料表单,该表单具有材料表单验证功能。前往你的activity_main.xml 文件并设置XML组件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:text="WELCOME BACK"
android:textColor="@color/purple_700"
android:layout_weight="0.2"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="0dp"
android:textSize="28sp"/>
<LinearLayout
android:layout_weight="0.4"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
</LinearLayout>
</LinearLayout>
我们将在子LinearLayout 里面创建我们的登录表单。一个基本的登录表单有InputText 字段,如电子邮件密码和电话号码。在这种情况下,假设我们想给我们的应用程序添加一个电子邮件字段。我们会使用一个EditText 组件来实现。然而,我们需要确保用户输入的文本是一个电子邮件。
下面是你如何使用材料设计来添加一个电子邮件EditText 。
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/login_emailContainer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:errorEnabled="true"
app:helperText="Required"
app:helperTextTextColor="@color/design_default_color_error">
<com.google.android.material.textfield.TextInputEditText
android:hint="Email"
android:layout_width="match_parent"
android:id="@+id/login_email"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"/>
</com.google.android.material.textfield.TextInputLayout>
这里我们有一个TextInputLayout ,它容纳了一个TextInputEditText ,类型是电子邮件。我们可以用材料属性对这些字段进行基本的表单验证。例如,由于TextInput 应该是Email 类型的,我们可以。
- 添加一个
android:inputType="textEmailAddress"属性,它将检查文本输入格式是否类似于电子邮件的格式。 - 一个
android:hint="Email",向用户显示这个字段需要一个电子邮件输入。 - 一个
app:helperText="Required",向用户显示这个字段在提交表单前总是需要的。 app:errorEnabled="true"向用户显示一个错误提示,只要指定的字段没有与该字段相关的必要的有效输入。
我们可以继续向我们的应用程序添加更多的字段。
<com.google.android.material.textfield.TextInputLayout
app:counterMaxLength="16"
android:id="@+id/login_passwordContainer"
android:layout_margin="8dp"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:counterEnabled="true"
android:layout_width="match_parent"
app:helperText="Required"
android:layout_height="wrap_content"
app:helperTextTextColor="@color/design_default_color_error"
app:errorEnabled="true"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:layout_height="wrap_content"
android:id="@+id/login_password"
android:layout_width="match_parent"
android:maxLength="16"
android:hint="Password"
android:inputType="textPassword"
android:lines="1"
/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
app:counterEnabled="true"
android:id="@+id/login_phoneContainer"
app:counterMaxLength="10"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_margin="8dp"
android:layout_width="match_parent"
app:errorEnabled="true"
android:layout_height="wrap_content"
app:helperText="Required"
app:helperTextTextColor="@color/design_default_color_error">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:id="@+id/login_phone"
android:layout_height="wrap_content"
android:inputType="number"
android:hint="Phone Number"
android:lines="1"/>
</com.google.android.material.textfield.TextInputLayout>
这里,我们又添加了两个字段:密码和电话号码。我们增加了更多的TextInput 验证检查,确保你的应用程序的输入有输入数据的一致性。
比如说。
android:inputType="textPassword"和 ,表明每个输入字段分别接纳了一个密码和一个数字。android:inputType="number"- 属性
android:maxLength="16",只允许用户输入准确的字符数。当计数器检查和最大字符数达到后,用户就可以向该字段添加更多的字符。 app:helperText="Required"以显示用户在提交表单前需要填写这个字段。app:errorEnabled="true"来捕捉输入错误和文本不匹配。- 我们还添加了一个
app:counterMaxLength。这将检查单个TextInput的最大字符数。app:counterEnabled="true"将保持计数并显示这个字符,以便用户可以了解他们可以添加到单个字段的最大字符数。
现在让我们添加一个按钮,它将帮助我们使用Kotlin代码处理复杂的验证逻辑。
<com.google.android.material.button.MaterialButton
android:layout_marginTop="60dp"
android:layout_width="290dp"
android:layout_margin="4dp"
android:text="Login"
android:layout_gravity="center"
android:layout_height="62dp"
android:id="@+id/login_button"/>
你可以运行你的应用程序来检查上述表单是否正确设置。

用数据绑定进行验证
我们已经使用材料来创建和执行基本的表单验证。现在让我们使用数据绑定来在用户提交这些输入之前验证表单输入。
数据绑定是一种机制,它允许你连接不同来源的值。它允许你将XML布局中的用户界面(UI)组件与数据源绑定。这使你能够将用户界面组件与应用逻辑联系起来。
我们可以使用数据绑定的概念来检查表单的有效性。一个表单涉及到向文本字段添加值。因此,我们可以将表单的UI连接到应用域对象,以根据用户的输入自动更新UI。
要在你的Kotlin项目中设置数据绑定,请前往build.gradle 文件并添加以下插件。
plugins {
id 'kotlin-kapt'
}
然后在android {} 内添加以下数据绑定buildFeatures 。
buildFeatures{
viewBinding = true
}
前往MainActivity.kt ,并初始化dataBinding 。首先是ActivityMainBinding ,它反映了tools:context=".MainActivity" 所指定的XML布局上下文。在AppCompatActivity() 的正下方添加以下内容。
private lateinit var activityMainBinding: ActivityMainBinding
然后在onCreate() 方法中初始化ActivityMainBinding 。在这里,我们将用下面两行代码取代通常的setContentView(R.layout.activity_main) 。
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
现在我们可以开始使用数据绑定来验证我们的表单。我们将检查和验证每个字段。
检查密码是否有效
我们将创建一个函数validPassword() ,并使用以下检查来验证密码输入是否有效,基于我们希望用户提交的密码。
private fun validPassword(): String? {
val passwordText = activityMainBinding.loginPassword.text.toString()
if(passwordText.length < 8) {
return "Minimum 8 Character Password"
}
if(!passwordText.matches(".*[A-Z].*".toRegex())) {
return "Must Contain 1 Upper-case Character"
}
if(!passwordText.matches(".*[a-z].*".toRegex())) {
return "Must Contain 1 Lower-case Character"
}
if(!passwordText.matches(".*[@#\$%^&+=].*".toRegex())) {
return "Must Contain 1 Special Character (@#\$%^&+=)"
}
return null
}
这是一个简单的检查。当用户输入密码时,它必须至少有八个字符。否则,这将触发一个错误,用户将被要求输入一个至少有八个字符的密码。
在另一端,密码字符计数器将只接受由app:counterMaxLength="16" 指定的最多16个字符的密码。
对于一个标准的密码,建议添加特殊字符并混合小写和大写字母。在这种情况下,我们使用Regex 来验证输入的密码是否有这种字符。如果没有,每个密码验证检查都会向用户端抛出一个错误,并通知他们根据当前的密码值来添加什么。
检查电子邮件是否有效
我们将创建一个函数checkIfEmailIsValid() ,根据我们希望用户提交的电子邮件值检查密码输入是否有效。
private fun checkIfEmailIsValid(): String? {
val emailInputText = activityMainBinding.loginEmail.text.toString()
activityMainBinding.loginEmail.doOnTextChanged { text, start, before, count ->
if(!Patterns.EMAIL_ADDRESS.matcher(emailInputText).matches()){
activityMainBinding.loginEmail.error = "Invalid Email Address"
}
else{
activityMainBinding.loginEmail.error = null
}
}
}
这里我们将使用自定义的EMAIL_ADDRESS 模式。这将检查输入的电子邮件,确保它与有效的电子邮件相匹配。如果用户输入了一个错误的电子邮件,这将返回"Invalid Email Address" 。
检查电话号码是否有效
我们将创建一个函数checkValidPhoneNumber() ,并验证电话号码的输入是否有效。
private fun checkValidPhoneNumber(): String? {
val phoneText = activityMainBinding.loginPhone.text.toString()
if(!phoneText.matches(".*[0-9].*".toRegex())){
return "Must be all Digits"
}
if(phoneText.length != 10){
return "Must be 10 Digits"
}
return null
}
这里,一个电话号码必须是数字。我们使用材料手工指定android:inputType="number" 。这将只允许用户输入数字类型的输入。然而,我们可以在我们的数据绑定中添加一个Regex,以根据用户的输入更新用户界面。我们还指定了app:counterMaxLength="10" 。因此,一个电话号码必须至少是十位数。然而,如果用户输入的数字超过十位,我们要将其作为一个错误返回,并通知用户该字段的电话号码"Must be 10 Digits" 。
处理表单提交
这个验证将在用户点击登录按钮时被处理。现在让我们把setOnClickListener 添加到loginButton 。我们将创建一个函数login() ,返回一个有效的表单和一个无效的表单提交的错误。
private fun login() {
activityMainBinding.loginEmailContainer.helperText = checkIfEmailIsValid()
activityMainBinding.loginPasswordContainer.helperText = validPassword()
activityMainBinding.loginPhoneContainer.helperText = checkValidPhoneNumber()
val checkIfEmailIsValid = activityMainBinding.loginEmailContainer.helperText == null
val validPassword = activityMainBinding.loginPasswordContainer.helperText == null
val checkValidPhoneNumber = activityMainBinding.loginPhoneContainer.helperText == null
if (checkIfEmailIsValid && validPassword && checkValidPhoneNumber) {
Toast.makeText(this,"Valid Form", Toast.LENGTH_SHORT).show()
resetForm()
}
else
Toast.makeText(this, "Invalid Form", Toast.LENGTH_SHORT).show()
}
在这里我们将把已经添加的输入值与我们的应用域绑定,并检查每个值是否有效。这个检查将在用户点击登录按钮时发生。继续往前走,在onCreate() 方法中加入以下内容:setOnClickListener 。
activityMainBinding.loginButton.setOnClickListener { login() }
当用户点击loginButton ,而所有的输入值都是有效的,将显示一个祝酒信息Valid Form 。否则,将显示Invalid Form 信息。
当用户成功地提交了有效的值,我们要重置表单的输入。继续创建一个resetForm() 函数,如下图所示。
private fun resetForm() {
activityMainBinding.loginEmail.text = null
activityMainBinding.loginPassword.text = null
activityMainBinding.loginPhone.text = null
activityMainBinding.loginPasswordContainer.helperText = "Required"
activityMainBinding.loginEmailContainer.helperText = "Required"
activityMainBinding.loginPhoneContainer.helperText = "Required"
}
这将清除输入并将其重置为默认值,并有一个"Required" 的帮助文本。
每个字段都会根据错误的输入向用户显示一条信息。例如,如果电子邮件是无效的,我们要更新用户界面并向用户显示电子邮件的值是"Invalid Email Address" 。
要做到这一点,在所有的表单域函数中添加一个setOnFocusChangeListener 。这样,每个不正确的输入都会以正确的错误信息来更新UI。继续添加以下setOnFocusChangeListener 函数,并根据视图ID将它们绑定到XML UI上。
private fun passwordInputTextOnFocusListener() {
activityMainBinding.loginPassword.setOnFocusChangeListener { _, focused ->
if(!focused){
activityMainBinding.loginPasswordContainer.helperText = validPassword()
}
}
}
private fun emailInputTextOnFocusListener() {
activityMainBinding.loginEmail.setOnFocusChangeListener { _, focused ->
if(!focused){
activityMainBinding.loginEmailContainer.helperText = checkIfEmailIsValid()
}
}
}
private fun phoneInputTextOnFocusListener() {
activityMainBinding.loginPhone.setOnFocusChangeListener { _, focused ->
if(!focused){
activityMainBinding.loginPhoneContainer.helperText = checkValidPhoneNumber()
}
}
}
最后,在onCreate() 方法中调用这些函数。
emailInputTextOnFocusListener()
passwordInputTextOnFocusListener()
phoneInputTextOnFocusListener()
我们的应用程序验证检查已经完成。你可以运行它们来测试所有的工作是否正确。
试着在文本字段中添加数值,并点击登录按钮来验证它们。

如果你根据表单验证提交了正确的输入,这将重置表单并显示你提交的值是有效的。
总结
在本教程中,我们已经涵盖并演示了Android studio中表单验证的基础知识。设置你所需要的用户,这是非常直接的。这可以确保数据的一致性并减少生产错误。
我希望你发现这些工具很有用,测试起来很简单,而且很容易构建应用程序。