目前代码已经上传到GitHub,里面有博客里面Material Design系列的所有代码
GitHub Material Design
1、什么是TextInputLayout?
TextInputLayout是22.2.0新添加的控件, 要和EditText(或EditText的子类)结合使用,并且只能包含一个EditText(或EditText的子类),这一点尤其重要,在做用户注册的时候遇到了TextInputLayout里面有获取验证码的按钮,布局的时候出现问题了,具体的解决方法详见下文,TextInputLayout的继承关系如下图所示。
2、为什么要用TextInputLayout?
遵循Material Design的设计,很多APP在用户登录、注册的页面中都使用了TextInputLayout的控件,在一些iOS的APP中也能发现这种想过,通过一些细微的动画效果以及改变颜色,能达到很炫酷的效果,相比传统的EditText,在用户输入信息的时,hint(提示)会自动上移,并且输入框的下划线会高亮,并能够把输入校验的错误能够在控件下面展示,不用Toast弹出提示,并且自带设置密码框的显示与隐藏,效果如下图所示。
3、如何使用TextInputLayout?
3.1 首先在build.gradle 引入design的库
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:design:26.1.0'
3.2 其次在xml文件中添加一下代码
3.3在activity中的设置
package com.codingsnail.materialdesigndemo.view
import CommonUtils
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.Editable
import android.text.TextWatcher
import android.widget.Toast
import com.codingsnail.materialdesigndemo.R
import kotlinx.android.synthetic.main.activity_text_input_login.*
import org.jetbrains.anko.sdk25.coroutines.onClick
/**
* Created by Snail on 3/1/2018 11:31 AM
* Contact with [email protected]
*/
class TextInputLoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_text_input_login)
initView()
}
private fun initView() {
et_phone.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
text_input_layout_phone.isErrorEnabled = false
}
override fun afterTextChanged(s: Editable) {
}
})
et_pwd.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
text_input_layout_pwd.isErrorEnabled = false
}
override fun afterTextChanged(s: Editable) {
}
})
btn_login.onClick {
invalidLogin()
}
}
private fun invalidLogin() {
if (!CommonUtils.verifyMobile(et_phone!!.text.toString().trim())) {
text_input_layout_phone.error = getString(R.string.error_field_phone)
return
}
if (!CommonUtils.verifyLoginPwd(et_pwd!!.text.toString().trim())) {
text_input_layout_pwd.error = getString(R.string.error_incorrect_password)
return
}
Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show()
}
companion object {
fun startActivity(context: Context) {
context.startActivity(Intent(context, TextInputLoginActivity::class.java))
}
}
}
这样就能完成如上git图所看到的所有功能啦!
4、TextInputLayout的重要属性讲解
4.1 达到上面效果我们需要做到的步骤
XML中配置的如上图所示,这样就可以基本完成TextInputLayout的功能了,但是想使用TextInputLayout自带的错误提示功能,在代码中还需要设置以下两点。
4.1.1 需要给TextInputEditText添加 addTextChangedListener监听,当文本有变化的时候需要动态的去设置,整个项目都是用Kotlin写的,Java的写法也是一样,只是语法不一样。
text_input_layout_pwd.isErrorEnabled = false
4.1.2 校验错误的时候去设置错误提示
可以看到完成1、2点以后就可以使用TextInputLayout的错误提示功能了
4.2 如何改变默认的颜色,能够适配自己APP颜色风格的UI
如果我们不进行颜色设置的话,那么我们字体的颜色以及下划线的颜色一定和colorPrimary、colorPrimaryDark、colorAccent颜色是一样的。
- #ff6f7272
- #ffd8d8d8
- #ff3586fe
- #ff3586fe
然后在我们的AndroidManifest.xml 里面的 application里面运用我们设置的主题就可以改变颜色了。
4.3 如何改变光标的颜色
如果我们不做配置的话,EditText的光标的颜色是和系统的colorAccent的颜色一样的,给editText设置光标颜色只需要设置一个属性即可。
在XML中为这个editText运用这个style即可
4.4 如何设置最大数量限制?
这个只需要在TextInputLayout里面设置几个属性就可以了
counterMaxLength 设置最大长度限制
counterEnabled 是否开启超出限制后的提示
counterOverflowTextAppearance 超出限制后hint 的颜色,以及EditText 下划线的颜色 16/11 提示文字的颜色以及提示字体的大小都是在这个里面设置的
4.5 密码功能的小眼睛的显示与隐藏?
随着互联网的发展,很多用户的密码会很长,很麻烦,在输入的时候提示密码不对,这时候需要动态的可以看到密码的显示和隐藏密码,这种功能在TextInputLayout出来之前我们都是通过去标记一个初始状态,然后点击图片的时候去改变状态,然后设置editText的内容为可见,有了TextInputLayout以后,我们只需要去设置不同状态下显示的图片就可以了,省去了显示眼睛不同状态下图片的复杂的业务逻辑,具体的代码如下:
login_pwd_eye_selector的代码如下:
下面为密码开关的一些属性。
app:passwordToggleEnabled:设置 password 开关是否可用。
app:passwordToggleTint:设置 password 开关图标的 tint 着色。
app:passwordToggleTintMode:设置 password tint 的模式。
app:passwordToggleDrawable:设置 password 开关图标。
setPasswordVisibilityToggleDrawable:设置 password 开关图标。
isPasswordVisibilityToggleEnabled:设置 password 开关图标 是否可见。
setPasswordVisibilityToggleTintList:设置 password 开关图标的 tint。
setPasswordVisibilityToggleTintMode:设置 password 开关图标的 tint 模式。
getPasswordVisibilityToggleDrawable:设置 password 开关图标。
4.6 使用过程中的请求验证码显示错位的问题
在上图中可以看到TextInputLayout中有一个获取验证码的按钮,因为TextInputLayout里面只能有EditText以及EditText的子类,所以我们想把获取验证码的按钮放在里面是不可能的。
最开始的时候的解决方案是TextInputLayout 外面套一层 RelativeLayout,然后把获取验证码这个Button 在RelativeLayout里面居中,最后发现这样写确实可以,但是当这个输入框有错误提示的时候,这个RelativeLayout的高度会变高,那么这个时候按钮的位置会在输入框的线上,所以最后把这个高度居中改为了直接距离上部20dp,这样问题就解决了。