Android Design Support Library使用详解——TextInputLayout与TextInputEditText

TextInputLayout

在谷歌的Material Design中,文本输入是这样表现的:当用户点击输入框想要输入文字时,若是输入框是空的,那么它的提示文字(hint)就会变小而且同时移动到输入框的上方;若是文字不为空,则上方一直浮着这个提示文字(见https://material.google.com/components/text-fields.html#text-fields-input )。而且在I/O大会的视频上,咱们能够看到整个的动画过程很优美流畅。在design support library中,TextInputLayout就是提供了它的实现。css

使用

经过TextInputLayout来实现上述这种效果很简单,就是在布局代码中每个EditText外面再套上一个TextInputLayout就能够了,代码以下。注意一个TextInputLayout只能套一个EditText,不然会抛异常。html

<android.support.design.widget.TextInputLayout  android:id="@+id/mobile_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/image_title">
    <EditText  android:id="@+id/mobile" style="@style/InputEditText.Login" android:drawableLeft="@drawable/icon_small_phone" android:hint="@string/hint_mobile" android:inputType="number" android:maxLength="11"/>
</android.support.design.widget.TextInputLayout>

编译运行,效果出现。
这里写图片描述java

显示错误消息

除了显示提示文字,TextInputLayout还提供了显示错误消息的接口。显示的方法也很简单,之前咱们是经过TextView的setError(String)来显示,如今改成调用TextInputLayout的setError(String)就能够了。代码以下:android

ViewParent parent = editText.getParent();
    if (parent instanceof TextInputLayout) {
        ((TextInputLayout)parent).setError(message);
    }
    editText.setError(message);

错误消息会直接显示在编辑框下面,而且不像EditText那样必需要得到焦点才能显示出来。如图所示:
这里写图片描述markdown

除了显示错误消息以外,咱们还须要清空错误消息,毕竟不能在用户改正以后还一直显示它吧。清空错误消息很简单,只须要调用它的API inputLayout.setErrorEnabled(false);便可。好比咱们能够在用户修改EditText时调用它:app

ViewParent viewParent = inputText.getParent();
    if (viewParent != null && viewParent instanceof TextInputLayout) {
        final TextInputLayout inputLayout = (TextInputLayout) viewParent;
        inputText.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                inputLayout.setErrorEnabled(false);
            }
        });
    }

统计输入字数

TextInputLayout还封装了输入框的输入字数的统计。这一特性在一些字数受限的功能中但是大有用处,好比发个微博提交个用户反馈,一般都会限定一个最大字数,于是须要显示给用户已经输入了多少个字。
统计字数默认是不开启的,咱们能够在属性里配置:ide

<android.support.design.widget.TextInputLayout  android:id="@+id/password_layout" app:counterEnabled="true" app:counterTextAppearance="@style/counter" app:counterMaxLength="8" app:counterOverflowTextAppearance="@style/counterOverflow" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/mobile_layout" android:layout_marginBottom="@dimen/margin_double">

counterOverflow定义:布局

<style name="counterOverflow"> <item name="android:textColor">@color/red</item> </style>

咱们能够只配置counterEnabled,这样的话它就只会显示输入的字数。而counterTextAppearance属性则用于配置计数文本外观。counterMaxLength用于配置最大字数,当配置了它时,就必须再配置counterOverflowTextAppearance,不然当用户输入的字数超过这个最大字数时会引起异常。
下图是咱们配置后的运行效果:
这里写图片描述动画

其余属性与方法请参数API文档,这里再也不赘述。google

TextInputEditText

在上一节中,咱们能够看到TextInputLayout与EditText在搭配使用当中,对于所需的功能都处理得很是好,那么,为何还要有TextInputEditText呢?
缘由很简单,TextInputEditText是为了填坑的。
当咱们的界面处于横屏时,点击一个EditText,默认状况下不是在它下面弹出键盘,而是进入到输入法的一个全屏的输入界面(经过配置android:imeOptions="flagNoExtractUi"能够设为直接在当前界面显示)。
通常在咱们要弹出输入法时,它会与对应的View创建一个链接,用于二者之间的互动,好比获取输入提示hint,而后在刚才所述的状况中显示到输入法的输入界面上。可是当咱们为EditText外面套上一个TextInputLayout时,TextInputLayout会拿到EditText的hint显示出来并把EditText自己的hint设为空。这样若是跳到输入法的输入界面上,就显示不了咱们所设置的提示文本了。因此TextInputEditText重写了EditText的onCreateInputConnection(EditorInfo outAttrs)方法,把父容器的hint内容传给EditorInfo,下面就是它惟一作的事情:

@Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        final InputConnection ic = super.onCreateInputConnection(outAttrs);
        if (ic != null && outAttrs.hintText == null) {
            // If we don't have a hint and our parent is a TextInputLayout, use it's hint for the
            // EditorInfo. This allows us to display a hint in 'extract mode'.
            final ViewParent parent = getParent();
            if (parent instanceof TextInputLayout) {
                outAttrs.hintText = ((TextInputLayout) parent).getHint();
            }
        }
        return ic;
    }

因此当咱们使用了TextInputLayout时,就须要把咱们的EditText换成TextInputEditText。
下面两张图分别是使用EditText及TextInputEditText的运行效果:
使用EditText,没有提示文本
使用TextInputEditText有提示文本

相关文章
相关标签/搜索