Android Design Support Library--TextInputLayout的使用

引言

Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2,我准备从最简单的控件开始,逐渐延伸,把新控件都给熟悉一遍。

先从看起来最简单的控件开始,也就是TextInputLayout,说实话TextInputLayout 我所见到的平常用的并不多,它的大体作用是在我们正常的EditText左上角显示出一个浮动标签,这个标签的内容就是我们设置的android:hint 属性的值。

先来看一下它的继承结构:

可以很清晰的看到我们的TextInputLayout 继承于LinearLayout ,那么很明显这是一个布局,需要配合它的子控件来显示出想要的效果,这里谷歌把它专门设计用来包裹EditText(或者EditText的子类),然后当用户进行输入动作的时候我们设置的android:hint 提示就会以动画的形式运动到左上角,谷歌官方提供的最简单的使用示例如下:


 " data-snippet-id="ext.ff48bc1841d0ab40fb6f56eda80da593" data-snippet-saved="false" data-codota-status="done"> <android.support.design.widget.TextInputLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">

     <android.support.design.widget.TextInputEditText
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:hint="@string/form_username"/>

 </android.support.design.widget.TextInputLayout>

有些人可能会奇怪,之前说好的TextInputLayout 是用来包裹EditText 的,为什么这里出现了TextInputEditText ,先别急,我们看一下谷歌官方对这个控件的描述:

A special sub-class of EditText designed for use as a child of TextInputLayout.

Using this class allows us to display a hint in the IME when in ‘extract‘ mode.

大意是说,这只是一种特殊的EditText 的子类,用来在‘extract‘ mode 下在输入法编辑器中显示我们的hint提示信息,这里的‘extract‘ mode 其实就是全屏模式,谷歌官方对它的解释是有时候你的输入框的UI界面很大,大的不能与你自己的应用程序的UI结合起来,这时候就可以切换到全屏模式来输入,这么说可能不太明白,上图:

比如说,下面这种情况使用的是EditText

我们看到下面那里输入框已经很大了,然后你点击输入框进行输入,会发现这个现象:

你进入到了全屏模式输入,但是界面上空空如也,对比一下使用TextInputEditText 的情况:

看到左上角的文字了嘛,这是我们在之前设置的android:hint 属性的值,这么一看这两者的区别的就一目了然了,但是说实话TextInputEditText 用到的地方还是很有限的,所以日常开发我们还是使用TextInputLayout 去包裹EditText 来实现浮动标签的功能。

以上图片出自 感谢万能的stackoverflow

接下来看看TextInputLayout里面有什么方法

因为它是继承自LinearLayout的所以理论上LinearLayout 有的属性它全都有,这里我们只看有关它本身的属性:

属性名 相关方法 描述
app:counterEnabled setCounterEnabled(boolean) 设置是否显示一个计数器,布尔值
app:counterMaxLength setCounterMaxLength(int) 设置计数器的最大计数数值,整型
app:errorEnabled setErrorEnabled(boolean) 设置是否显示一个错误信息,布尔值
app:hintAnimationEnabled setHintAnimationEnabled(boolean) 设置是否要显示输入状态时候的动画效果,布尔值
app:hintEnabled setHintEnabled(boolean) 设置是否要用这个浮动标签的功能,布尔值
app:hintTextAppearance setHintTextAppearance(int) 设置提示文字的样式(注意这里是运行了动画效果之后的样式)


这里我们通过一个简单的Demo来了解以上这些属性,简单起见我们就做一个登录界面,这个界面长这样:

先上布局文件:


" data-snippet-id="ext.5d8d55d83bfbc72cf59a7f0f8bbb6b61" data-snippet-saved="false" data-codota-status="done"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    tools:context="com.test.textinputlayoutdemo.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="65dp"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/layout_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            >

            <EditText
                android:id="@+id/input_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/EnterName"
                android:singleLine="true" />
        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:id="@+id/layout_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:counterEnabled="true"
            app:counterMaxLength="11"
            >

            <EditText
                android:id="@+id/input_password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/EnterPassWord"
                android:inputType="textPassword"
                android:singleLine="true" />
        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:id="@+id/layout_email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >

            <EditText
                android:id="@+id/input_email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/EnterEmail"
                android:inputType="textEmailAddress"
                 />
        </android.support.design.widget.TextInputLayout>

        <Button
            android:id="@+id/login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            android:background="@color/colorPrimary"
            android:text="@string/login"
            android:textColor="#ffffff"
            android:textSize="20sp"
            android:textStyle="bold" />
    </LinearLayout>

</RelativeLayout>

代码如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText input_name, input_password, input_email;
    private TextInputLayout layout_name, layout_password, layout_email;
    private Button btn_login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initWidget();

    }

    private void initWidget() {
        input_name = (EditText) findViewById(R.id.input_name);
        input_password = (EditText) findViewById(R.id.input_password);
        input_email = (EditText) findViewById(R.id.input_email);

        layout_name = (TextInputLayout) findViewById(R.id.layout_name);
        layout_password = (TextInputLayout) findViewById(R.id.layout_password);
        layout_email = (TextInputLayout) findViewById(R.id.layout_email);

        btn_login = (Button) findViewById(R.id.login);
        btn_login.setOnClickListener(this);

        //添加监听
        input_name.addTextChangedListener(new MyTextWatcher(input_name));
        input_password.addTextChangedListener(new MyTextWatcher(input_password));
        input_email.addTextChangedListener(new MyTextWatcher(input_email));
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.login:
                canLogin();
                break;
            default:
                break;

        }
    }

    /**
     * 判断是否可以登录的方法
     */
    private void canLogin() {
        if (!isNameValid()) {
            Toast.makeText(this, getString(R.string.check), Toast.LENGTH_SHORT).show();
            return;
        }
        if (!isPasswordValid()) {
            Toast.makeText(this, getString(R.string.check), Toast.LENGTH_SHORT).show();
            return;
        }
        if (!isEmailValid()) {
            Toast.makeText(this, getString(R.string.check), Toast.LENGTH_SHORT).show();
            return;
        }
        Toast.makeText(this, getString(R.string.login_success), Toast.LENGTH_SHORT).show();
    }

    public boolean isNameValid() {

        if (input_name.getText().toString().trim().equals("") || input_name.getText().toString().trim().isEmpty()) {
            layout_name.setError(getString(R.string.error_name));
            input_name.requestFocus();
            return false;
        }
        layout_name.setErrorEnabled(false);
        return true;
    }

    public boolean isPasswordValid() {
        if (input_password.getText().toString().trim().equals("") || input_password.getText().toString().trim().isEmpty()) {
            layout_password.setErrorEnabled(true);
            layout_password.setError(getResources().getString(R.string.error_password));
            input_password.requestFocus();
            return false;
        }
        layout_password.setErrorEnabled(false);
        return true;
    }

    public boolean isEmailValid() {
        String email = input_email.getText().toString().trim();
        if (TextUtils.isEmpty(email) || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
            layout_email.setErrorEnabled(true);
            layout_email.setError(getString(R.string.error_email));
            layout_email.requestFocus();
            return false;
        }
        layout_email.setErrorEnabled(false);
        return true;
    }

    //动态监听输入过程
    private class MyTextWatcher implements TextWatcher {

        private View view;

        private MyTextWatcher(View view) {
            this.view = view;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            switch (view.getId()) {
                case R.id.input_name:
                    isNameValid();
                    break;
                case R.id.input_password:
                    isPasswordValid();
                    break;
                case R.id.input_email:
                    isEmailValid();
                    break;

            }

        }
    }
}

先来看一下最终的实现效果:

可以很明显的看到,当我们同时设置了app:counterEnabledapp:counterMaxLength 属性时,我们输入的EditText 右下角会出现一个计数器还有一个最大输入字符数的数字显示,我们在输入名字这一栏设置最大输入为5个字符,所以当超过了5个字符的时候,EditText 的整个样式的颜色都会改变以示警告,如果我们只设置了app:counterEnabled 属性的话EditText 右下角一开始会出现一个0,随着输入字符的增多而逐步进行计数,注意如果设置了整个属性我们EditText 布局的高度会有一定的增大,具体的可以自己实践一下。

另外,我们在代码中设置了不同的饿输入类型,如果输入类型错误,我们就可以通过设置app:errorEnabled 来开启错误显示,此时需要通过在代码中调用 setError(string) 方法来设置显示的错误提示文字,当不需要的时候记得设置app:errorEnabled(false) 来取消错误提示,不然错误提示会一直存在。

注意: 当我们使用app:counterMaxLength 这个属性的时候,一定要设置 app:counterOverflowTextAppearance 属性,不然的话程序运行会报错,这个属性是设置当我们输入字符超过限定的个数时候EditText控件整体显示的样式,需要在style.xml文件里面定义一个自己的style,注意我们自定义的style的parent是TextAppearance.AppCompat.Small ,拿我上面的程序举例:

        #f3672b
    " data-snippet-id="ext.1695e4cac4c6fc02c34abdd74f3c445f" data-snippet-saved="false" data-codota-status="done">    <style name="MyOverflowText" parent="TextAppearance.AppCompat.Small">
        <item name="android:textColor">#f3672b</item>
    </style>

这样定义好后再在app:counterOverflowTextAppearance 里面设置这个style就行

关于自定义样式

有些人可能不喜欢官方提供的默认样式想要自己定义,下面说一下自定义几种样式的方法:

  • 如果你想更改下划线的颜色,只要在style.xml文件里面找到AppTheme:

        @color/colorPrimary
        @color/colorPrimaryDark
        @color/colorAccent
    " data-snippet-id="ext.7b6870eda182a16f499c25f9137a966b" data-snippet-saved="false" data-codota-status="done"> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

更改里面的colorAccent属性就行了

  • 如果你想更改错误提示的样式的话,也是在style.xml文件里面,自定义一个style,同样拿上面的程序举例:
        #ec4722
    " data-snippet-id="ext.ea38174bf63d09575a67ac17628913dc" data-snippet-saved="false" data-codota-status="done"><style name="MyErrorStyle">
        <item name="android:textColor">#ec4722</item>
    </style>

然后在xml文件TextInputLayout控件里面这么设置一下就行了:

app:errorTextAppearance="@style/MyErrorStyle"

包括前面提到的设置当输入字符大于我们限定个数字符时的样式,基本上我们可以很好地自定义出自己想要的style了,以上两种不提供演示,都很简单,可以自己去尝试。

最后

下一次准备分析SnackBar控件,很多东西说简单也简单,说不简单也不简单,就像做这个Demo我之前光看官方文档根本没有告诉有app:counterOverflowTextAppearance 这个属性的存在,也是一直查资料,还是要亲自去尝试一下才好,下面上源码(注意是AS文件)

参考:Android Material Design Floating Labels for EditText

Demo地址

项目GitHub地址

最后来个小提示,当我们在Android Studio中导入support design开发包的时候,版本号最好和v7包的版本号一致,不然有些时候会出现莫名其妙的错误:

    compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
    compile ‘com.android.support:appcompat-v7:23.0.1‘
    compile ‘com.android.support:design:23.0.1‘

有任何问题欢迎留言探讨~

时间: 2024-10-15 19:27:09

Android Design Support Library--TextInputLayout的使用的相关文章

Android Design Support Library(2)- TextInputLayout的使用

原创文章,转载请注明 http://blog.csdn.net/leejizhou/article/details/50494634 这篇文章介绍下Android Design Support Library中的TextInputLayout的使用,假设你还不知道怎么使用这个Design Library请參考 http://blog.csdn.net/leejizhou/article/details/50479934,TextInputLayout使你的EditText更具有Material

【翻】Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

译者地址:[翻]Android Design Support Library 的 代码实验--几行代码,让你的 APP 变得花俏 原文:Codelab for Android Design Support Library used in I/O Rewind Bangkok session--Make your app fancy with few lines of code 原文项目 demo: Lab-Android-DesignLibrary 双语对照地址: [翻-双语]Android D

Material Design 开发利器:Android Design Support Library 介绍

转自:https://blog.leancloud.cn/3306/ Android 5.0 Lollipop 是迄今为止最重大的一次发布,很大程度上是因为 material design —— 这是一门新的设计语言,它刷新了整个 Android 的用户体验.但是对于开发者来说,要设计出完全符合 material design 哲学的应用,是一个很大的挑战.Android Design Support Library 对此提供了很好的支持,里面汇集了很多重要的 material design 控

Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

译者地址:[翻]Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏 原文:Codelab for Android Design Support Library used in I/O Rewind Bangkok session----Make your app fancy with few lines of code 原文项目 demo: Lab-Android-DesignLibrary 双语对照地址: [翻-双语]Android

Android Design Support Library——Navigation View

前沿 Android 从5.0开始引入了Material design元素的设计,这种新的设计语言让整个安卓的用户体验焕然一新,google在Android Design Support Library中封装了一些重要的material design控件,在这之前其实github上也已经出现了许多各种各样的material design 控件,只不过现在google把有些控件标准化了,注意这个Android Design Support Library和Android Support Libra

Material Design with the Android Design Support Library

Material Design with the Android Design Support Library 原文http://www.sitepoint.com/material-design-android-design-support-library/ Material Design,Android 5.0发布时为android app 和其他平台app引入的一门新的设计语言. 它带来了一些新的UI组件,如“Floating Action Button”.实施这些新组件,同时确保向后兼容

如何使用android design support library

Android应用Design Support Library完全使用实例 - OPEN 开发经验库http://www.open-open.com/lib/view/open1433385856119.html Android MD风格相关控件小结 - 简书http://www.jianshu.com/p/5e6f2ae1d2ec 在android studio中引用这个库非常简单,只要在 build.gradle 文件中加上这段代码: compile 'com.android.support

Android Design Support Library使用详解

Android Design Support Library使用详解 Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件.最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2.这不得不说是一个良心之作. 使用S

【转】【翻】Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

转自:http://mrfufufu.github.io/android/2015/07/01/Codelab_Android_Design_Support_Library.html [翻]Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏 Jul 1, 2015 译者地址:[翻]Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏 原文:Codelab for Androi

Android Design Support Library 介绍

本文翻译自著名博客 Android Developers,原作者是 Ian Lake,点击此处可查看 原文 . Android 5.0 Lollipop 是迄今为止最重大的一次发布,很大程度上是因为 material design —— 这是一门新的设计语言,它刷新了整个 Android 的用户体验.但是对于开发者来说,要设计出完全符合 material design 哲学的应用,是一个很大的挑战.Android Design Support Library 对此提供了很好的支持,里面汇集了很多