TextInputLayout源码解析

  • 文章目录
  1. 效果图
  2. TextInputLayout的使用
  3. 源码解析
  • TextInputLayout继承自LinearLayout,配合EditText使用,可以实现MD风格效果
  1. 使用前添加依赖
          
          
    1. compile 'com.android.support:appcompat-v7:23.4.0'
    2. compile 'com.android.support:design:23.4.0'
  2. 在xml文件中,EditText作为子空间放到TextInputLayout中
          
          
    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. android:layout_width="match_parent"
    3. android:layout_height="match_parent"
    4. android:orientation="vertical">
    5. <include layout="@layout/common_toolbar" />
    6. <TextView
    7. android:layout_width="wrap_content"
    8. android:layout_height="wrap_content"
    9. android:layout_gravity="center_horizontal"
    10. android:layout_marginTop="50dp"
    11. android:text="登录"
    12. android:textColor="@color/colorPrimary"
    13. android:textSize="38sp" />
    14. <android.support.design.widget.TextInputLayout
    15. android:id="@+id/til_username"
    16. android:layout_width="match_parent"
    17. android:layout_marginLeft="10dp"
    18. android:layout_marginRight="10dp"
    19. android:layout_height="wrap_content"
    20. android:layout_marginTop="30dp">
    21. <EditText
    22. android:id="@+id/et_username"
    23. android:layout_width="match_parent"
    24. android:layout_height="wrap_content"
    25. android:hint="手机号"
    26. android:textColor="@color/Black" />
    27. </android.support.design.widget.TextInputLayout>
    28. <android.support.design.widget.TextInputLayout
    29. android:id="@+id/til_password"
    30. android:layout_width="match_parent"
    31. android:layout_marginLeft="10dp"
    32. android:layout_marginRight="10dp"
    33. android:layout_height="wrap_content">
    34. <EditText
    35. android:id="@+id/et_password"
    36. android:layout_width="match_parent"
    37. android:layout_height="wrap_content"
    38. android:hint="密码"
    39. android:textColor="@color/Black" />
    40. </android.support.design.widget.TextInputLayout>
    41. <Button
    42. android:id="@+id/btn_login"
    43. android:layout_width="match_parent"
    44. android:layout_height="wrap_content"
    45. android:layout_margin="10dp"
    46. android:text="登录"
    47. android:textAllCaps="false" />
    48. </LinearLayout>
  3. 当EidtText获得焦点后提示信息往上移动
          
          
    1. tilUserName.setHint("手机号");
    2. tilPassword.setHint("密码");
  4. 设置EditText输入文字最大值并监听
          
          
    1. tilUserName.setCounterEnabled(true);
    2. tilUserName.setCounterMaxLength(11);
  5. 解决报错:java.lang.UnsupportedOperationException: Failed to resolve attribute at index:需要自己在主题中设置
           
           
    1. //在Theme主题的style中添加该item
    2. <item name="textColorError">@color/design_textinput_error_color_light</item>
  6. 当输入的信息不正确时,给出错误提示(例如手机格式不正确)
          
          
    1. tilUserName.setError("手机号最多11位");
           
           
    1.  //不显示错误信息
    2. tilUserName.setErrorEnabled(false);
  7. Activity代码
          
          
    1. public class TextInputLayoutActivity extends BaseActivity {
    2. /**
    3. * 正则表达式:验证密码
    4. */
    5. public static final String REGEX_PASSWORD = "^[a-zA-Z0-9]{6,16}$";
    6. /**
    7. * 正则表达式:验证手机号
    8. */
    9. public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
    10. @Override
    11. protected void onCreate(Bundle savedInstanceState) {
    12. super.onCreate(savedInstanceState);
    13. setContentView(R.layout.activity_text_input_layout);
    14. initToolBar();
    15. final TextInputLayout tilUserName = (TextInputLayout) findViewById(R.id.til_username);
    16. final TextInputLayout tilPassword = (TextInputLayout) findViewById(R.id.til_password);
    17. Button btnLogin = (Button) findViewById(R.id.btn_login);
    18. btnLogin.setOnClickListener(new View.OnClickListener() {
    19. @Override
    20. public void onClick(View v) {
    21. String phone = tilUserName.getEditText().getText().toString().trim();
    22. String password = tilPassword.getEditText().getText().toString().trim();
    23. boolean pass = true;
    24. tilUserName.setErrorEnabled(false);
    25. tilPassword.setErrorEnabled(false);
    26. if (!isMobile(phone)) {//输入的不是手机号
    27. tilUserName.setError("请输入正确的手机号");
    28. pass = false;
    29. }
    30. if (!isPassword(password)) {
    31. tilPassword.setError("密码至少6位");
    32. pass = false;
    33. }
    34. if (!pass) {
    35. return;
    36. }
    37. doLogin();
    38. }
    39. });
    40. //设置提示信息
    41. tilUserName.setHint("手机号");
    42. tilUserName.setCounterEnabled(true);
    43. tilUserName.setCounterMaxLength(11);
    44. tilPassword.setHint("密码");
    45. tilUserName.getEditText().addTextChangedListener(new TextWatcher() {
    46. @Override
    47. public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    48. }
    49. @Override
    50. public void onTextChanged(CharSequence s, int start, int before, int count) {
    51. if (s.toString().length() > 11) {
    52. tilUserName.setError("手机号最多11位");
    53. } else {
    54. tilUserName.setErrorEnabled(false);
    55. }
    56. }
    57. @Override
    58. public void afterTextChanged(Editable s) {
    59. }
    60. });
    61. }
    62. private void doLogin() {
    63. Toast.makeText(TextInputLayoutActivity.this, "登录验证通过", android.widget.Toast.LENGTH_SHORT).show();
    64. }
    65. public static boolean isMobile(String mobile) {
    66. return Pattern.matches(REGEX_MOBILE, mobile);
    67. }
    68. public static boolean isPassword(String password) {
    69. return Pattern.matches(REGEX_PASSWORD, password);
    70. }
    71. }
  • 源码解析
  • 构造函数:该类继承自LinearLayout,orientation为垂直
     
     
  1. public class TextInputLayout extends LinearLayout {
  2. public TextInputLayout(Context context) {
  3. this(context, null);
  4. }
  5. public TextInputLayout(Context context, AttributeSet attrs) {
  6. this(context, attrs, 0);
  7. }
  8. public TextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
  9. // Can't call through to super(Context, AttributeSet, int) since it doesn't exist on API 10
  10. super(context, attrs);
  11. ThemeUtils.checkAppCompatTheme(context);
  12. setOrientation(VERTICAL);
  13. setWillNotDraw(false);
  14. setAddStatesFromChildren(true);
  15. mCollapsingTextHelper.setTextSizeInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);
  16. mCollapsingTextHelper.setPositionInterpolator(new AccelerateInterpolator());
  17. mCollapsingTextHelper.setCollapsedTextGravity(Gravity.TOP | GravityCompat.START);
  18.  //获取xml设置的属性信息
  19. final TypedArray a = context.obtainStyledAttributes(attrs,
  20. R.styleable.TextInputLayout, defStyleAttr, R.style.Widget_Design_TextInputLayout);
  21. mHintEnabled = a.getBoolean(R.styleable.TextInputLayout_hintEnabled, true);
  22. setHint(a.getText(R.styleable.TextInputLayout_android_hint));
  23. mHintAnimationEnabled = a.getBoolean(
  24. R.styleable.TextInputLayout_hintAnimationEnabled, true);
  25. if (a.hasValue(R.styleable.TextInputLayout_android_textColorHint)) {
  26. mDefaultTextColor = mFocusedTextColor =
  27. a.getColorStateList(R.styleable.TextInputLayout_android_textColorHint);
  28. }
  29. final int hintAppearance = a.getResourceId(
  30. R.styleable.TextInputLayout_hintTextAppearance, -1);
  31. if (hintAppearance != -1) {
  32. setHintTextAppearance(
  33. a.getResourceId(R.styleable.TextInputLayout_hintTextAppearance, 0));
  34. }
  35. mErrorTextAppearance = a.getResourceId(R.styleable.TextInputLayout_errorTextAppearance, 0);
  36. final boolean errorEnabled = a.getBoolean(R.styleable.TextInputLayout_errorEnabled, false);
  37. final boolean counterEnabled = a.getBoolean(
  38. R.styleable.TextInputLayout_counterEnabled, false);
  39. setCounterMaxLength(
  40. a.getInt(R.styleable.TextInputLayout_counterMaxLength, INVALID_MAX_LENGTH));
  41. mCounterTextAppearance = a.getResourceId(
  42. R.styleable.TextInputLayout_counterTextAppearance, 0);
  43. mCounterOverflowTextAppearance = a.getResourceId(
  44. R.styleable.TextInputLayout_counterOverflowTextAppearance, 0);
  45. a.recycle();
  46. setErrorEnabled(errorEnabled);
  47. setCounterEnabled(counterEnabled);
  48. if (ViewCompat.getImportantForAccessibility(this)
  49. == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
  50. // Make sure we're important for accessibility if we haven't been explicitly not
  51. ViewCompat.setImportantForAccessibility(this,
  52. ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
  53. }
  54. ViewCompat.setAccessibilityDelegate(this, new TextInputAccessibilityDelegate());
  55. }
  56. }
  • 构造函数中主要处理
  1. 设置错误提示信息setErrorEnabled()
              
              
    1. public void setErrorEnabled(boolean enabled) {
    2. //巧妙的写法,判断如果和错误提示状态和之前是一样的,不用处理->学习
    3. if (mErrorEnabled != enabled) {
    4. if (mErrorView != null) {
    5. ViewCompat.animate(mErrorView).cancel();
    6. }
    7. if (enabled) {
    8.  //进入到这个条件中,表示之前之前状态是没有该错误提示空间,需要创建并添加
    9. mErrorView = new TextView(getContext());
    10. try {
    11. mErrorView.setTextAppearance(getContext(), mErrorTextAppearance);//在xml文件中设置错误信息样式
    12. } catch (Exception e) {
    13. // Probably caused by our theme not extending from Theme.Design*. Instead
    14. // we manually set something appropriate
    15.                    //使用系统的样式
    16. mErrorView.setTextAppearance(getContext(),
    17. android.support.v7.appcompat.R.style.TextAppearance_AppCompat_Caption);
    18. mErrorView.setTextColor(ContextCompat.getColor(
    19. getContext(), R.color.design_textinput_error_color_light));
    20. }
    21. mErrorView.setVisibility(INVISIBLE);//先隐藏
    22. ViewCompat.setAccessibilityLiveRegion(mErrorView,
    23. ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE);
    24. addIndicator(mErrorView, 0);//添加到Indicator中
    25. } else {//false的话,需要将该错误信息的背景和对象引用置空,并刷新界面
    26. mErrorShown = false;
    27. updateEditTextBackground();
    28. removeIndicator(mErrorView);
    29. mErrorView = null;
    30. }
    31. mErrorEnabled = enabled;
    32. }
    33. }
    在看下addIndicator()方法
               
               
    1. private void addIndicator(TextView indicator, int index) {
    2. if (mIndicatorArea == null) {
    3.            //发现,mIndicatorArea也是一个LinearLayout,且方向为横向摆放,EidtText长度信息也是放在该控件中
    4. mIndicatorArea = new LinearLayout(getContext());
    5. mIndicatorArea.setOrientation(LinearLayout.HORIZONTAL);
    6.            //将该控件mIndicatorArea添加至TextInputLayout中
    7. addView(mIndicatorArea, LinearLayout.LayoutParams.MATCH_PARENT,
    8. LinearLayout.LayoutParams.WRAP_CONTENT);
    9. // Add a flexible spacer in the middle so that the left/right views stay pinned
    10. final Space spacer = new Space(getContext());
    11. final LinearLayout.LayoutParams spacerLp = new LinearLayout.LayoutParams(0, 0, 1f);
    12. mIndicatorArea.addView(spacer, spacerLp);
    13. if (mEditText != null) {
    14. adjustIndicatorPadding();
    15. }
    16. }
    17. mIndicatorArea.setVisibility(View.VISIBLE);
    18.        //添加
    19. mIndicatorArea.addView(indicator, index);
    20. mIndicatorsAdded++;
    21. }
  2. 设置EditText长度提示信息setCounterEnable(),该方法和setErrorEnabled()方法类似
              
              
    1. public void setCounterEnabled(boolean enabled) {
    2. if (mCounterEnabled != enabled) {
    3. if (enabled) {
    4. mCounterView = new TextView(getContext());//新建
    5. mCounterView.setMaxLines(1);
    6. try {
    7. mCounterView.setTextAppearance(getContext(), mCounterTextAppearance);
    8. } catch (Exception e) {
    9. // Probably caused by our theme not extending from Theme.Design*. Instead
    10. // we manually set something appropriate
    11. mCounterView.setTextAppearance(getContext(),
    12. android.support.v7.appcompat.R.style.TextAppearance_AppCompat_Caption);
    13. mCounterView.setTextColor(ContextCompat.getColor(
    14. getContext(), R.color.design_textinput_error_color_light));
    15. }
    16. addIndicator(mCounterView, -1);//添加
    17. if (mEditText == null) {
    18. updateCounter(0);
    19. } else {
    20. updateCounter(mEditText.getText().length());
    21. }
    22. } else {
    23. removeIndicator(mCounterView);
    24. mCounterView = null;
    25. }
    26. mCounterEnabled = enabled;
    27. }
    28. }

  • ViewGroup的三个主流方法中处理逻辑
  1. draw()
                
                
    1. @Override
    2. public void draw(Canvas canvas) {
    3. super.draw(canvas);
    4. if (mHintEnabled) {
    5. mCollapsingTextHelper.draw(canvas);
    6. }
    7. }
    mHintEnabled默认为true:
                 
                 
    1. mHintEnabled = a.getBoolean(R.styleable.TextInputLayout_hintEnabled, true);
  2. onLayout()
                
                
    1. @Override
    2. protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    3. super.onLayout(changed, left, top, right, bottom);
    4. if (mHintEnabled && mEditText != null) {
    5. final int l = mEditText.getLeft() + mEditText.getCompoundPaddingLeft();
    6. final int r = mEditText.getRight() - mEditText.getCompoundPaddingRight();
    7. mCollapsingTextHelper.setExpandedBounds(l,
    8. mEditText.getTop() + mEditText.getCompoundPaddingTop(),
    9. r, mEditText.getBottom() - mEditText.getCompoundPaddingBottom());
    10. // Set the collapsed bounds to be the the full height (minus padding) to match the
    11. // EditText's editable area
    12. mCollapsingTextHelper.setCollapsedBounds(l, getPaddingTop(),
    13. r, bottom - top - getPaddingBottom());
    14. mCollapsingTextHelper.recalculate();
    15. }
    16. }

  • 问题一:TextInputLayout和EditText是如何关联的?
       
       
  1. @Override
  2. public void addView(View child, int index, ViewGroup.LayoutParams params) {
  3. if (child instanceof EditText) {
  4. setEditText((EditText) child);
  5. super.addView(child, 0, updateEditTextMargin(params));
  6. } else {
  7. // Carry on adding the View...
  8. super.addView(child, index, params);
  9. }
  10. }
关键方法为addView(child),该方法继承自ViewGroup,会将内部的EditText添加至TextInputLayout中
  • 再看setEditText()方法
         
         
  1. private void setEditText(EditText editText) {
  2. // If we already have an EditText, throw an exception
  3. if (mEditText != null) {
  4. throw new IllegalArgumentException("We already have an EditText, can only have one");
  5. }
  6. if (!(editText instanceof TextInputEditText)) {
  7. Log.i(LOG_TAG, "EditText added is not a TextInputEditText. Please switch to using that"
  8. + " class instead.");
  9. }
  10. mEditText = editText;
  11. // Use the EditText's typeface, and it's text size for our expanded text
  12. mCollapsingTextHelper.setTypefaces(mEditText.getTypeface());
  13. mCollapsingTextHelper.setExpandedTextSize(mEditText.getTextSize());
  14. final int editTextGravity = mEditText.getGravity();
  15. mCollapsingTextHelper.setCollapsedTextGravity(
  16. Gravity.TOP | (editTextGravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK));
  17. mCollapsingTextHelper.setExpandedTextGravity(editTextGravity);
  18. // Add a TextWatcher so that we know when the text input has changed
  19. mEditText.addTextChangedListener(new TextWatcher() {
  20. @Override
  21. public void afterTextChanged(Editable s) {
  22. updateLabelState(true);
  23. if (mCounterEnabled) {
  24. updateCounter(s.length());
  25. }
  26. }
  27. @Override
  28. public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  29. @Override
  30. public void onTextChanged(CharSequence s, int start, int before, int count) {}
  31. });
  32. // Use the EditText's hint colors if we don't have one set
  33. if (mDefaultTextColor == null) {
  34. mDefaultTextColor = mEditText.getHintTextColors();
  35. }
  36. // If we do not have a valid hint, try and retrieve it from the EditText, if enabled
  37. if (mHintEnabled && TextUtils.isEmpty(mHint)) {
  38. setHint(mEditText.getHint());
  39. // Clear the EditText's hint as we will display it ourselves
  40. mEditText.setHint(null);
  41. }
  42. if (mCounterView != null) {
  43. updateCounter(mEditText.getText().length());
  44. }
  45. if (mIndicatorArea != null) {
  46. adjustIndicatorPadding();
  47. }
  48. // Update the label visibility with no animation
  49. updateLabelState(false);
  50. }
  • 该方法里主要处理
  • 监听EditText输入:在监听回调中,可以获取到EditText输入文本的长度,并且展示
                
                
    1. private void updateCounter(int length) {
    2. boolean wasCounterOverflowed = mCounterOverflowed;
    3. if (mCounterMaxLength == INVALID_MAX_LENGTH) {
    4. mCounterView.setText(String.valueOf(length));
    5. mCounterOverflowed = false;
    6. } else {
    7. mCounterOverflowed = length > mCounterMaxLength;
    8. if (wasCounterOverflowed != mCounterOverflowed) {
    9. mCounterView.setTextAppearance(getContext(), mCounterOverflowed ?
    10. mCounterOverflowTextAppearance : mCounterTextAppearance);
    11. }
    12. mCounterView.setText(getContext().getString(R.string.character_counter_pattern,
    13. length, mCounterMaxLength));
    14. }
    15. if (mEditText != null && wasCounterOverflowed != mCounterOverflowed) {
    16. updateLabelState(false);
    17. updateEditTextBackground();
    18. }
    19. }
  • EidtText控件中hint隐藏文字在获取到焦点的时候,所做的网上动画效果:调用的方法就是updateLabelState()
                
                
    1. private void updateLabelState(boolean animate) {
    2. final boolean hasText = mEditText != null && !TextUtils.isEmpty(mEditText.getText());//EditText文本是否为空
    3. final boolean isFocused = arrayContains(getDrawableState(), android.R.attr.state_focused);//EditText是否获取到焦点
    4. final boolean isErrorShowing = !TextUtils.isEmpty(getError());
    5. if (mDefaultTextColor != null) {
    6. mCollapsingTextHelper.setExpandedTextColor(mDefaultTextColor.getDefaultColor());
    7. }
    8. if (mCounterOverflowed && mCounterView != null) {
    9. mCollapsingTextHelper.setCollapsedTextColor(mCounterView.getCurrentTextColor());
    10. } else if (isFocused && mFocusedTextColor != null) {
    11. mCollapsingTextHelper.setCollapsedTextColor(mFocusedTextColor.getDefaultColor());
    12. } else if (mDefaultTextColor != null) {
    13. mCollapsingTextHelper.setCollapsedTextColor(mDefaultTextColor.getDefaultColor());
    14. }
    15. if (hasText || isFocused || isErrorShowing) {
    16. // We should be showing the label so do so if it isn't already
    17. collapseHint(animate);
    18. } else {
    19. // We should not be showing the label so hide it
    20. expandHint(animate);
    21. }
    22. }
    动画
                 
                 
    1.  //关闭动画,如果有正在运行的动画,先关闭在开启
    2. private void collapseHint(boolean animate) {
    3. if (mAnimator != null && mAnimator.isRunning()) {
    4. mAnimator.cancel();
    5. }
    6. if (animate && mHintAnimationEnabled) {
    7. animateToExpansionFraction(1f);
    8. } else {
    9. mCollapsingTextHelper.setExpansionFraction(1f);
    10. }
    11. }
    12. private void expandHint(boolean animate) {
    13. if (mAnimator != null && mAnimator.isRunning()) {
    14. mAnimator.cancel();
    15. }
    16. if (animate && mHintAnimationEnabled) {
    17. animateToExpansionFraction(0f);
    18. } else {
    19. mCollapsingTextHelper.setExpansionFraction(0f);
    20. }
    21. }
                  
                  
    1. private void animateToExpansionFraction(final float target) {
    2. if (mCollapsingTextHelper.getExpansionFraction() == target) {
    3. return;
    4. }
    5. if (mAnimator == null) {
    6. mAnimator = ViewUtils.createAnimator();
    7. mAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
    8. mAnimator.setDuration(ANIMATION_DURATION);
    9.            //动画监听
    10. mAnimator.setUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() {
    11. @Override
    12. public void onAnimationUpdate(ValueAnimatorCompat animator) {
    13. mCollapsingTextHelper.setExpansionFraction(animator.getAnimatedFloatValue());//最后交给了CollapsingTextHelp类去处理
    14. }
    15. });
    16. }
    17. mAnimator.setFloatValues(mCollapsingTextHelper.getExpansionFraction(), target);
    18. mAnimator.start();//开启动画
    19. }
  • CollapsingTextHelp类就是TextInputLayout的辅助类,主要用于展示EditText提示信息,和动画处理
           
           
  1.  //作为TextInputLayout的全局变量
  2. private final CollapsingTextHelper mCollapsingTextHelper = new CollapsingTextHelper(this);
  • 设置提示信息
                  
                  
    1. public void setHint(@Nullable CharSequence hint) {
    2. if (mHintEnabled) {
    3. setHintInternal(hint);
    4. sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
    5. }
    6. }
                   
                   
    1. private void setHintInternal(CharSequence hint) {
    2. mHint = hint;
    3. mCollapsingTextHelper.setText(hint);//交给CollapsingTextHelp处理
    4. }
  • setError()方法逻辑:内部会调用setErrorEnabled(true);
                  
                  
    1. public void setError(@Nullable final CharSequence error) {
    2. mError = error;
    3. if (!mErrorEnabled) {
    4. if (TextUtils.isEmpty(error)) {
    5. // If error isn't enabled, and the error is empty, just return
    6. return;
    7. }
    8. // Else, we'll assume that they want to enable the error functionality
    9. setErrorEnabled(true);
    10. }
    11. // Only animate if we've been laid out already and we have a different error
    12. final boolean animate = ViewCompat.isLaidOut(this)
    13. && !TextUtils.equals(mErrorView.getText(), error);
    14. mErrorShown = !TextUtils.isEmpty(error);
    15. // Cancel any on-going animation
    16. ViewCompat.animate(mErrorView).cancel();
    17. if (mErrorShown) {
    18. mErrorView.setText(error);
    19. mErrorView.setVisibility(VISIBLE);
    20. if (animate) {
    21. if (ViewCompat.getAlpha(mErrorView) == 1f) {
    22. // If it's currently 100% show, we'll animate it from 0
    23. ViewCompat.setAlpha(mErrorView, 0f);
    24. }
    25.                //动画执行
    26. ViewCompat.animate(mErrorView)
    27. .alpha(1f)
    28. .setDuration(ANIMATION_DURATION)
    29. .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
    30. .setListener(new ViewPropertyAnimatorListenerAdapter() {
    31. @Override
    32. public void onAnimationStart(View view) {
    33. view.setVisibility(VISIBLE);
    34. }
    35. }).start();
    36. } else {
    37. // Set alpha to 1f, just in case
    38. ViewCompat.setAlpha(mErrorView, 1f);
    39. }
    40. } else {
    41. if (mErrorView.getVisibility() == VISIBLE) {
    42. if (animate) {
    43. ViewCompat.animate(mErrorView)
    44. .alpha(0f)
    45. .setDuration(ANIMATION_DURATION)
    46. .setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR)
    47. .setListener(new ViewPropertyAnimatorListenerAdapter() {
    48. @Override
    49. public void onAnimationEnd(View view) {
    50. mErrorView.setText(error);
    51. view.setVisibility(INVISIBLE);
    52. }
    53. }).start();
    54. } else {
    55. mErrorView.setText(error);
    56. mErrorView.setVisibility(INVISIBLE);
    57. }
    58. }
    59. }
    60. updateEditTextBackground();
    61. updateLabelState(true);
    62. }
    63. 16年最后一发
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值