您的位置:首页 > 移动开发 > Android开发

Android Design TextInputLayout 解析,带你深入TextInputLayout

2015-09-02 13:44 507 查看
出来工作好几年了,最近冷静下来总结发现自己技术真心不咋的,所以决定开始写博客来锻炼自己。

想了想写什么好呢,又不是大牛,所以写不出非常高深的好文章出来,所以从最基础的写起走。2015 I/O大会谷歌推出了 Android Design Support Library,所以就更新下来看了看。从最简单的开始写吧,来看TextInputLayout,为什么要使用TextInputLayout,这个控件用于在多个输入框时,用户可能忘记hint内容,这个时候hint提醒就会在上方显示,也能用于判断,界面挺美的。先直上效果图。



这就是TextInputLayout实现的效果。接下来我们先看他的使用方法再去看源码。

使用前我们更新android sdk,最近不需要***就可以更新androidsdk建议全部更新。本次需要使用到的是Extras下的Android Support Library。使用的开发工具是Android studio。

新建一个Activity。然后导入lib库。右击项目选择Open Module Settings --->选择Dependencies--->选择library dependency--->然后找到design---->ok.导入库的步骤就完了。



导入后大家可以去项目的build.gradle里面看看,会在dependencies里面多一句

compile 'com.android.support:design:23.0.0'


接下来我们再看看我们的xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                tools:context=".TextInputLayoutActivity">

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

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

</RelativeLayout>
非常简单就是在<android.support.design.widget.TextInputLayout>容器里面加了一个EditText。xml布局完成之后就是Activity里面编写 了。

package com.xiaomeng.learn;

import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;

/**
 * create by xiaomeng on 2015/9/2
 */
public class TextInputLayoutActivity extends AppCompatActivity {

    /***
     * Design的输入容器(子控件需要包含EditText)
     */
    TextInputLayout mTextInputLayout;
    /**
     * EditText输入框
     */
    EditText mEditText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_input_layout);
        mTextInputLayout=(TextInputLayout)findViewById(R.id.a_textinputlayout);
        //设置hint提示
        mTextInputLayout.setHint("请输入用户名");
        //获取TextInputLayout下的输入框
        mEditText=mTextInputLayout.getEditText();
        //设置对EditText输入的监听事件
        mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                //这儿判断操作,如果输入错误可以给用户提示
                if(s.length()<5){
                    mTextInputLayout.setErrorEnabled(true);
                    mTextInputLayout.setError("用户名不能小于6位");
                }else{
                    mTextInputLayout.setErrorEnabled(false);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

    }
}


然后就可以运行项目了,嘿嘿,看效果吧。

TextInputLayout既可以在输入时把提示语显示与EditText的上方,又能把错误信息提示显示在EditText的下方。

TextInputLayout需要注意的几点:1、TextInputLayout不能单独使用,必须和EditText嵌套使用。

2、 1个TextInputLayout只能包1个EditTExt。

再来看看比较常用的方法

1、setHint();设置提示语

2、setError();设置错误显示信息

3、setErrorEnabled();设置错误信息是否显示。true显示,false不显示。

4、getEditText();得到EditText的控件实例。

基本使用说到这儿就完了,接下来看看源码,源码总共是398行。从上往下看。

public class TextInputLayout extends LinearLayout {
    private static final int ANIMATION_DURATION = 200;
    private EditText mEditText;
    private CharSequence mHint;
    private Paint mTmpPaint;
    private boolean mErrorEnabled;
    private TextView mErrorView;
    private int mErrorTextAppearance;
    private ColorStateList mDefaultTextColor;
    private ColorStateList mFocusedTextColor;
    private final CollapsingTextHelper mCollapsingTextHelper;
    private boolean mHintAnimationEnabled;
    private ValueAnimatorCompat mAnimator;
首先,TextInputLayout继承自LinearLayout。

第一个ANIMATION_DURATION=200,很容易看出这应该是一个动画时间。

再来看看其他的,还用到了EditText、mHint(看名字就知道是hint提示语了)、Paint、boolean类型的mErrorEnabled(很容易就会想到在之前我们有一个setErrorEnabled()的方法)、mErrorView等。我们通过变量去找这些变量的分别有什么作用。看完这些你继续往下看可能慢慢会有点迷糊了,那我们就从public方法去看,因为public方法是公共的,是能够被外部调用的。
首先看最简单的。

public void setHint(@Nullable CharSequence hint) {
        this.mHint = hint;
        this.mCollapsingTextHelper.setText(hint);
        this.sendAccessibilityEvent(2048);
    }
setHint()方法,第一步赋值,第二步设置文本,第三步,咋一看好像不咋用到,看到Event,我就想肯定是和事件相关的。这个sendAccessibilityEvent()是View里面的一个方法,是事件分发相关的一个内容。

public void setErrorEnabled(boolean enabled) {
        if(this.mErrorEnabled != enabled) {
            if(this.mErrorView != null) {
                ViewCompat.animate(this.mErrorView).cancel();
            }

            if(enabled) {
                this.mErrorView = new TextView(this.getContext());
                this.mErrorView.setTextAppearance(this.getContext(), this.mErrorTextAppearance);
                this.mErrorView.setVisibility(4);
                this.addView(this.mErrorView);
                if(this.mEditText != null) {
                    ViewCompat.setPaddingRelative(this.mErrorView, ViewCompat.getPaddingStart(this.mEditText), 0, ViewCompat.getPaddingEnd(this.mEditText), this.mEditText.getPaddingBottom());
                }
            } else {
                this.removeView(this.mErrorView);
                this.mErrorView = null;
            }

            this.mErrorEnabled = enabled;
        }

    }


这个是设置是否显示错误信息提示的方法。首先判断enabled,然后判断errorview是否存在,如果存在就会把动画取消,然后再重实例化重新设置。

public void setError(@Nullable CharSequence error) {
        if(!this.mErrorEnabled) {
            if(TextUtils.isEmpty(error)) {
                return;
            }

            this.setErrorEnabled(true);
        }

        if(!TextUtils.isEmpty(error)) {
            ViewCompat.setAlpha(this.mErrorView, 0.0F);
            this.mErrorView.setText(error);
            ViewCompat.animate(this.mErrorView).alpha(1.0F).setDuration(200L).setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR).setListener(new ViewPropertyAnimatorListenerAdapter() {
                public void onAnimationStart(View view) {
                    view.setVisibility(0);
                }
            }).start();
            ViewCompat.setBackgroundTintList(this.mEditText, ColorStateList.valueOf(this.mErrorView.getCurrentTextColor()));
        } else if(this.mErrorView.getVisibility() == 0) {
            ViewCompat.animate(this.mErrorView).alpha(0.0F).setDuration(200L).setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR).setListener(new ViewPropertyAnimatorListenerAdapter() {
                public void onAnimationEnd(View view) {
                    view.setVisibility(4);
                }
            }).start();
            TintManager tintManager = TintManager.get(this.getContext());
            ViewCompat.setBackgroundTintList(this.mEditText, tintManager.getTintList(drawable.abc_edit_text_material));
        }

        this.sendAccessibilityEvent(2048);
    }


看源码才发现不用设置setErrorEnabled()为true也是可以的。因为这里会调用setErrorEnabled(true)。

然后就讲到这儿吧。其实源码也不是那么深奥。如果静下心来仔细看源码的话。在源码中可以看一些别人写代码的风格。最后希望大家不要喷得太厉害。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: