如果我们想写一个登陆界面是不是一般都写两组TextView,EditText及一个Button,不过体验并不是太好,等等这些麻烦的的处理在Material Design TextInputLayout出现后得到了极大改善,我们可以做最少的事达到最好的效果
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
该项目的用户界面非常简单。它显示了一个欢迎标签(如果有的话,可以很容易地用徽标替换)和两个EditText
元素,一个用于用户名,另一个用于密码。布局还包括一个触发登录序列的按钮。背景颜色是漂亮,平坦,浅灰色。
可以看到并不是非常美观,下载我们引入 TextInputLayout 稍作改动
TextInputLayout
我们终于到达了本教程中最有趣的部分。一个 TextInputLayout
小部件的行为与LinearLayout
它完全一样,它只是一个包装器。TextInputLayout
只接受一个子元素,类似于a ScrollView
。子元素必须是一个EditText
元素。
final TextInputLayout usernameWrapper = findViewById(R.id.usernameWrapper);
final TextInputLayout passwordWrapper = findViewById(R.id.passwordWrapper);
usernameWrapper.setHint("Username");
passwordWrapper.setHint("Password");
是不是美观了点呢?
但我们遇到了一个问题,每次输入后键盘不能即使收起,这个问题该如何解决呢?
onClick
方法首先必须处理按钮单击。有很多方法可以处理按钮点击。
public class StartActivity extends AppCompatActivity implements View.OnClickListener {
private LinearLayout linearLayout;
private TextInputLayout usernameWrapper;
private TextInputLayout passwordWrapper;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
iniViews();
}
private void iniViews(){
linearLayout = findViewById(R.id.background);
usernameWrapper = findViewById(R.id.usernameWrapper);
passwordWrapper = findViewById(R.id.passwordWrapper);
btn = findViewById(R.id.btn);
linearLayout.setOnClickListener(this);
usernameWrapper.setOnClickListener(this);
passwordWrapper.setOnClickListener(this);
btn.setOnClickListener(this);
usernameWrapper.setHint("Username");
passwordWrapper.setHint("Password");
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.usernameWrapper:
break;
case R.id.passwordWrapper:
break;
case R.id.btn:
break;
case R.id.background:
hideKeyboard();
break;
default:
break;
}
}
private void hideKeyboard() {
View view = getCurrentFocus();
if (view != null) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).
hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
这时我们就会进一步想,怎么知道用户输入的是一个正确的邮箱地址或者正确格式的密码呢?
我使用维基百科建议的 有关电子邮件有效性的指南编写了以下正则表达式。
/^[a-zA-Z0-9#_~!$&'()*+,;=:."(),:;<>@\[\]\\]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*$/
所以我们就可以根据这个表达式建立一个类来实现完整的功能了
public class EmailManager {
private static final String EMAIL_PATTERN = "^[a-zA-Z0-9#_~!$&'()*+,;=:.\"(),:;<>@\\[\\]\\\\]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$";
private Pattern pattern = Pattern.compile(EMAIL_PATTERN);
private Matcher matcher;
public boolean validateEmail(String email) {
matcher = pattern.matcher(email);
return matcher.matches();
}
public boolean validatePassword(String password) {
return password.length() > 5;
}
}
如何获得输入框中的文字呢?
正如我所说的,TextInputLayout
只是一个包装,但不像 LinearLayout
并且 ScrollView
,你可以使用特定的方法获得它的子元素 getEditText
。没有必要使用findViewById
。
如果 TextInputLayout
不包含EditText
,则 getEditText
返回null
所以要小心a NullPointException
。
String username = usernameWrapper.getEditText().getText().toString();
String password = usernameWrapper.getEditText().getText().toString();
不会满足眼前效果的文门可能会想,如何监听文字的变化呢?
TextInputLayout
错误处理简单快捷。所需的方法是 setErrorEnabled
和setError
。
setError
设置将显示在下方的红色错误消息EditText
。如果传递的参数是null
,则清除错误消息。它还将整个EditText
小部件的颜色更改为红色。
setErrorEnabled
启用错误功能。这直接影响布局的大小,增加较低的填充以为错误标签腾出空间。在设置错误消息之前启用此功能setError
意味着在显示错误时此布局不会更改大小。您应该结合这两种方法进行一些测试,以便您实际看到 我在说什么。
另一个有趣的事实是,如果尚未启用错误功能并且您调用setError
传递非null参数,setErrorEnabled(true)
则会自动调用。
@Override
public void onClick(View v) {
String username = usernameWrapper.getEditText().getText().toString();
String password = usernameWrapper.getEditText().getText().toString();
switch (v.getId()){
case R.id.usernameWrapper:
if (!new EmailManager().validateEmail(username)) {
usernameWrapper.setError("Not a valid email address!");
}else {
usernameWrapper.setErrorEnabled(false);
}
break;
case R.id.passwordWrapper:
if (!new EmailManager().validatePassword(password)) {
passwordWrapper.setError("Not a valid password!");
}else {
passwordWrapper.setErrorEnabled(false);
}
break;
case R.id.btn:
break;
case R.id.background:
hideKeyboard();
break;
default:
break;
}
}
如果我们想要对改变颜色又该怎么办呢?
Google非常清楚地编写了设计支持库。每个小部件的颜色都直接从style.xml文件中指定的主题颜色中绘制 。只需打开它并将colorAccent
项目添加到活动主题即可更改表单的颜色方案。
<item name="colorAccent">@color/purple</item>
到此为止所有效果基本都实现了,欢迎大家关注我继续 Material design 的学习