TextInputLayout.java revision c5b63021dfda1dd155775a0b4845c5ca3c70b1b0
1c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes/* 2c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * Copyright (C) 2015 The Android Open Source Project 3c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * 4c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 5c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * you may not use this file except in compliance with the License. 6c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * You may obtain a copy of the License at 7c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * 8c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 9c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * 10c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * Unless required by applicable law or agreed to in writing, software 11c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 12c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * See the License for the specific language governing permissions and 14c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * limitations under the License. 15c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes */ 16c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 17c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banespackage android.support.design.widget; 18c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 19c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.content.Context; 20c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.content.res.ColorStateList; 21c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.content.res.TypedArray; 22c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.graphics.Canvas; 23c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.graphics.Color; 24c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.graphics.Paint; 25c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.os.Handler; 26c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.os.Message; 27c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.support.design.R; 28c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.support.v4.view.AccessibilityDelegateCompat; 29c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.support.v4.view.ViewCompat; 30c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.support.v4.view.ViewPropertyAnimatorListenerAdapter; 31c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 32c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.text.Editable; 33c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.text.TextUtils; 34c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.text.TextWatcher; 35c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.util.AttributeSet; 36c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.util.TypedValue; 37c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.view.Gravity; 38c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.view.View; 39c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.view.ViewGroup; 40c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.view.accessibility.AccessibilityEvent; 41c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.view.animation.AccelerateInterpolator; 42c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.view.animation.Animation; 43c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.view.animation.Transformation; 44c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.widget.EditText; 45c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.widget.LinearLayout; 46c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banesimport android.widget.TextView; 47c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 48c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes/** 49c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * Layout which wraps an {@link android.widget.EditText} to show a floating label when 50c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * the hint is hidden due to the user inputting text. 51c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes */ 52c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banespublic class TextInputLayout extends LinearLayout { 53c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 54c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private static final long ANIMATION_DURATION = 200; 55c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private static final int MSG_UPDATE_LABEL = 0; 56c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 57c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private EditText mEditText; 58c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private CharSequence mHint; 59c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 60c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private boolean mErrorEnabled; 61c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private TextView mErrorView; 62c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private int mErrorTextAppearance; 63c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 64c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private ColorStateList mLabelTextColor; 65c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 66c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private final CollapsingTextHelper mCollapsingTextHelper; 67c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private final Handler mHandler; 68c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 69c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public TextInputLayout(Context context) { 70c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes this(context, null); 71c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 72c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 73c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public TextInputLayout(Context context, AttributeSet attrs) { 74c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes this(context, attrs, 0); 75c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 76c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 77c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public TextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { 78c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super(context, attrs, defStyleAttr); 79c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 80c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes setOrientation(VERTICAL); 81c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes setWillNotDraw(false); 82c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 83c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper = new CollapsingTextHelper(this); 84c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mHandler = new Handler(new Handler.Callback() { 85c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 86c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public boolean handleMessage(Message message) { 87c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes switch (message.what) { 88c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes case MSG_UPDATE_LABEL: 89c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes updateLabelVisibility(true); 90c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return true; 91c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 92c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return false; 93c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 94c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes }); 95c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 96c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setTextSizeInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR); 97c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setPositionInterpolator(new AccelerateInterpolator()); 98c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setCollapsedTextVerticalGravity(Gravity.TOP); 99c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 100c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final TypedArray a = context.obtainStyledAttributes(attrs, 101c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes R.styleable.TextInputLayout, defStyleAttr, R.style.Widget_Design_TextInputLayout); 102c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mHint = a.getText(R.styleable.TextInputLayout_android_hint); 103c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 104c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final int hintAppearance = a.getResourceId( 105c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes R.styleable.TextInputLayout_hintTextAppearance, -1); 106c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (hintAppearance != -1) { 107c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setCollapsedTextAppearance(hintAppearance); 108c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 109c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 110c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorTextAppearance = a.getResourceId(R.styleable.TextInputLayout_errorTextAppearance, 0); 111c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final boolean errorEnabled = a.getBoolean(R.styleable.TextInputLayout_errorEnabled, false); 112c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 113c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // We create a ColorStateList using the specified text color, combining it with our 114c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // theme's textColorHint 115c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mLabelTextColor = createLabelTextColorStateList( 116c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.getCollapsedTextColor()); 117c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 118c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setCollapsedTextColor(mLabelTextColor.getDefaultColor()); 119c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setExpandedTextColor(mLabelTextColor.getDefaultColor()); 120c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 121c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes a.recycle(); 122c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 123c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (errorEnabled) { 124c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes setErrorEnabled(true); 125c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 126c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 127c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (ViewCompat.getImportantForAccessibility(this) 128c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { 129c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Make sure we're important for accessibility if we haven't been explicitly not 130c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.setImportantForAccessibility(this, 131c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); 132c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 133c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 134c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.setAccessibilityDelegate(this, new TextInputAccessibilityDelegate()); 135c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 136c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 137c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 138c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void addView(View child, int index, ViewGroup.LayoutParams params) { 139c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (child instanceof EditText) { 140c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes params = setEditText((EditText) child, params); 141c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super.addView(child, 0, params); 142c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } else { 143c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Carry on adding the View... 144c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super.addView(child, index, params); 145c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 146c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 147c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 148c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private LayoutParams setEditText(EditText editText, ViewGroup.LayoutParams lp) { 149c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // If we already have an EditText, throw an exception 150c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (mEditText != null) { 151c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes throw new IllegalArgumentException("We already have an EditText, can only have one"); 152c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 153c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mEditText = editText; 154c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 155c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Use the EditText's text size for our expanded text 156c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setExpandedTextSize(mEditText.getTextSize()); 157c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 158c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Add a TextWatcher so that we know when the text input has changed 159c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mEditText.addTextChangedListener(new TextWatcher() { 160c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 161c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void afterTextChanged(Editable s) { 162c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mHandler.sendEmptyMessage(MSG_UPDATE_LABEL); 163c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 164c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 165c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 166c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void beforeTextChanged(CharSequence s, int start, int count, int after) { 167c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 168c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 169c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 170c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void onTextChanged(CharSequence s, int start, int before, int count) { 171c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 172c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes }); 173c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 174c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Add focus listener to the EditText so that we can notify the label that it is activated. 175c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Allows the use of a ColorStateList for the text color on the label 176c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mEditText.setOnFocusChangeListener(new OnFocusChangeListener() { 177c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 178c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void onFocusChange(View view, boolean focused) { 179c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mHandler.sendEmptyMessage(MSG_UPDATE_LABEL); 180c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 181c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes }); 182c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 183c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // If we do not have a valid hint, try and retrieve it from the EditText 184c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (TextUtils.isEmpty(mHint)) { 185c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes setHint(mEditText.getHint()); 186c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Clear the EditText's hint as we will display it ourselves 187c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mEditText.setHint(null); 188c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 189c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 190c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (mErrorView != null) { 191c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Add some start/end padding to the error so that it matches the EditText 192c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.setPaddingRelative(mErrorView, ViewCompat.getPaddingStart(mEditText), 193c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 0, ViewCompat.getPaddingEnd(mEditText), mEditText.getPaddingBottom()); 194c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 195c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 196c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Update the label visibility with no animation 197c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes updateLabelVisibility(false); 198c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 199c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Create a new FrameLayout.LayoutParams so that we can add enough top margin 200c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // to the EditText so make room for the label 201c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes LayoutParams newLp = new LayoutParams(lp); 202c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes Paint paint = new Paint(); 203c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes paint.setTextSize(mCollapsingTextHelper.getExpandedTextSize()); 204c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes newLp.topMargin = (int) -paint.ascent(); 205c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 206c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return newLp; 207c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 208c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 209c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private void updateLabelVisibility(boolean animate) { 210c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes boolean hasText = !TextUtils.isEmpty(mEditText.getText()); 211c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes boolean isFocused = mEditText.isFocused(); 212c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 213c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setCollapsedTextColor(mLabelTextColor.getColorForState( 214c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes isFocused ? FOCUSED_STATE_SET : EMPTY_STATE_SET, 215c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mLabelTextColor.getDefaultColor())); 216c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 217c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (hasText || isFocused) { 218c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // We should be showing the label so do so if it isn't already 219c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes collapseHint(animate); 220c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } else { 221c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // We should not be showing the label so hide it 222c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes expandHint(animate); 223c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 224c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 225c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 226c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes /** 227c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * @return the {@link android.widget.EditText} text input 228c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes */ 229c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public EditText getEditText() { 230c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return mEditText; 231c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 232c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 233c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes /** 234c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * Set the hint to be displayed in the floating label 235c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes */ 236c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void setHint(CharSequence hint) { 237c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mHint = hint; 238c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setText(hint); 239c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 240c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); 241c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 242c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 243c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes /** 244c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * Whether the error functionality is enabled or not in this layout. Enabling this 245c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * functionality before setting an error message via {@link #setError(CharSequence)}, will mean 246c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * that this layout will not change size when an error is displayed. 247c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * 248c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * @attr R.attr.errorEnabled 249c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes */ 250c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void setErrorEnabled(boolean enabled) { 251c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (mErrorEnabled != enabled) { 252c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (enabled) { 253c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView = new TextView(getContext()); 254c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView.setTextAppearance(getContext(), mErrorTextAppearance); 255c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView.setVisibility(INVISIBLE); 256c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes addView(mErrorView); 257c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 258c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (mEditText != null) { 259c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Add some start/end padding to the error so that it matches the EditText 260c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.setPaddingRelative(mErrorView, ViewCompat.getPaddingStart(mEditText), 261c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 0, ViewCompat.getPaddingEnd(mEditText), mEditText.getPaddingBottom()); 262c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 263c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } else { 264c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes removeView(mErrorView); 265c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView = null; 266c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 267c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorEnabled = enabled; 268c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 269c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 270c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 271c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes /** 272c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * Sets an error message that will be displayed below our {@link EditText}. If the 273c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * {@code error} is {@code null}, the error message will be cleared. 274c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * <p> 275c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * If the error functionality has not been enabled via {@link #setErrorEnabled(boolean)}, then 276c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * it will be automatically enabled if {@code error} is not empty. 277c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * 278c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes * @param error Error message to display, or null to clear 279c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes */ 280c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void setError(CharSequence error) { 281c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (!mErrorEnabled) { 282c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (TextUtils.isEmpty(error)) { 283c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // If error isn't enabled, and the error is empty, just return 284c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return; 285c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 286c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Else, we'll assume that they want to enable the error functionality 287c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes setErrorEnabled(true); 288c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 289c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 290c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (!TextUtils.isEmpty(error)) { 291c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView.setText(error); 292c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView.setVisibility(VISIBLE); 293c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.setAlpha(mErrorView, 0f); 294c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.animate(mErrorView) 295c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .alpha(1f) 296c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .setDuration(ANIMATION_DURATION) 297c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR) 298c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .setListener(null) 299c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .start(); 300c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } else { 301c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (mErrorView.getVisibility() == VISIBLE) { 302c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes ViewCompat.animate(mErrorView) 303c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .alpha(0f) 304c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .setDuration(ANIMATION_DURATION) 305c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR) 306c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes .setListener(new ViewPropertyAnimatorListenerAdapter() { 307c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 308c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void onAnimationEnd(View view) { 309c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView.setText(null); 310c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mErrorView.setVisibility(INVISIBLE); 311c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 312c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes }).start(); 313c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 314c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 315c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 316c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); 317c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 318c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 319c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 320c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void draw(Canvas canvas) { 321c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super.draw(canvas); 322c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.draw(canvas); 323c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 324c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 325c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 326c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 327c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super.onLayout(changed, left, top, right, bottom); 328c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 329c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.onLayout(changed, left, top, right, bottom); 330c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 331c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (mEditText != null) { 332c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final int l = mEditText.getLeft() + mEditText.getPaddingLeft(); 333c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final int r = mEditText.getRight() - mEditText.getPaddingRight(); 334c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 335c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setExpandedBounds(l, 336c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mEditText.getTop() + mEditText.getPaddingTop(), 337c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes r, mEditText.getBottom() - mEditText.getPaddingBottom()); 338c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 339c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Set the collapsed bounds to be the the full height (minus padding) to match the 340c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // EditText's editable area 341c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setCollapsedBounds(l, getPaddingTop(), 342c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes r, bottom - top - getPaddingBottom()); 343c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 344c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 345c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 346c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private void collapseHint(boolean animate) { 347c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (animate) { 348c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes animateToExpansionFraction(1f); 349c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } else { 350c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setExpansionFraction(1f); 351c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 352c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 353c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 354c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private void expandHint(boolean animate) { 355c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (animate) { 356c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes animateToExpansionFraction(0f); 357c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } else { 358c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setExpansionFraction(0f); 359c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 360c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 361c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 362c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private void animateToExpansionFraction(final float target) { 363c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final float current = mCollapsingTextHelper.getExpansionFraction(); 364c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 365c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes Animation anim = new Animation() { 366c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 367c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes protected void applyTransformation(float interpolatedTime, Transformation t) { 368c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes mCollapsingTextHelper.setExpansionFraction( 369c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes AnimationUtils.lerp(current, target, interpolatedTime)); 370c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 371c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes }; 372c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes anim.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR); 373c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes anim.setDuration(ANIMATION_DURATION); 374c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes startAnimation(anim); 375c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 376c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 377c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private ColorStateList createLabelTextColorStateList(int color) { 378c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final int[][] states = new int[2][]; 379c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final int[] colors = new int[2]; 380c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes int i = 0; 381c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 382c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes // Focused 383c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes states[i] = FOCUSED_STATE_SET; 384c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes colors[i] = color; 385c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes i++; 386c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 387c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes states[i] = EMPTY_STATE_SET; 388c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes colors[i] = getThemeAttrColor(android.R.attr.textColorHint); 389c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes i++; 390c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 391c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return new ColorStateList(states, colors); 392c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 393c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 394c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private int getThemeAttrColor(int attr) { 395c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes TypedValue tv = new TypedValue(); 396c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (getContext().getTheme().resolveAttribute(attr, tv, true)) { 397c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return tv.data; 398c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } else { 399c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes return Color.MAGENTA; 400c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 401c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 402c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 403c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes private class TextInputAccessibilityDelegate extends AccessibilityDelegateCompat { 404c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 405c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 406c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super.onInitializeAccessibilityEvent(host, event); 407c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes event.setClassName(TextInputLayout.class.getSimpleName()); 408c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 409c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 410c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 411c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) { 412c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super.onPopulateAccessibilityEvent(host, event); 413c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 414c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final CharSequence text = mCollapsingTextHelper.getText(); 415c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (!TextUtils.isEmpty(text)) { 416c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes event.getText().add(text); 417c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 418c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 419c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 420c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes @Override 421c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) { 422c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes super.onInitializeAccessibilityNodeInfo(host, info); 423c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes info.setClassName(TextInputLayout.class.getSimpleName()); 424c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes 425c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final CharSequence text = mCollapsingTextHelper.getText(); 426c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (!TextUtils.isEmpty(text)) { 427c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes info.setText(text); 428c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 429c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (mEditText != null) { 430c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes info.setLabelFor(mEditText); 431c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 432c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes final CharSequence error = mErrorView != null ? mErrorView.getText() : null; 433c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes if (!TextUtils.isEmpty(error)) { 434c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes info.setContentInvalid(true); 435c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes info.setError(error); 436c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 437c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 438c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes } 439c5b63021dfda1dd155775a0b4845c5ca3c70b1b0Chris Banes}