Java tutorial
/* * Copyright 2015 Rey Pham. * Modifications Copyright(C) 2016 Fred Grott * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.github.shareme.gwsmaterialuikit.library.material.widget; import android.annotation.TargetApi; import android.content.ClipboardManager; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.view.GravityCompat; import android.support.v7.widget.AppCompatAutoCompleteTextView; import android.support.v7.widget.AppCompatEditText; import android.support.v7.widget.AppCompatMultiAutoCompleteTextView; import android.text.Editable; import android.text.InputFilter; import android.text.Layout; import android.text.Spannable; import android.text.TextPaint; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.text.TextWatcher; import android.text.method.KeyListener; import android.text.method.MovementMethod; import android.text.method.PasswordTransformationMethod; import android.text.method.TransformationMethod; import android.text.style.URLSpan; import android.util.AttributeSet; import android.util.TypedValue; import android.view.ActionMode; import android.view.Gravity; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.CorrectionInfo; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.widget.AdapterView; import android.widget.AutoCompleteTextView; import android.widget.CursorAdapter; import android.widget.Filter; import android.widget.Filterable; import android.widget.ListAdapter; import android.widget.MultiAutoCompleteTextView; import android.widget.Scroller; import com.github.shareme.gwsmaterialuikit.library.R; import com.github.shareme.gwsmaterialuikit.library.material.app.ThemeManager; import com.github.shareme.gwsmaterialuikit.library.material.drawable.DividerDrawable; import com.github.shareme.gwsmaterialuikit.library.material.util.ThemeUtil; import com.github.shareme.gwsmaterialuikit.library.material.util.ViewUtil; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.Locale; @SuppressWarnings("unused") public class EditText extends FrameLayout implements ThemeManager.OnThemeChangedListener { private boolean mLabelEnable; private boolean mLabelVisible; protected int mSupportMode; protected int mAutoCompleteMode; /** * Indicate this EditText should not show a support text. */ public static final int SUPPORT_MODE_NONE = 0; /** * Indicate this EditText should show a helper text, or error text if it's set. */ public static final int SUPPORT_MODE_HELPER = 1; /** * Indicate this EditText should show a helper text, along with error text if it's set. */ public static final int SUPPORT_MODE_HELPER_WITH_ERROR = 2; /** * Indicate this EditText should show a char counter text. */ public static final int SUPPORT_MODE_CHAR_COUNTER = 3; public static final int AUTOCOMPLETE_MODE_NONE = 0; public static final int AUTOCOMPLETE_MODE_SINGLE = 1; public static final int AUTOCOMPLETE_MODE_MULTI = 2; private ColorStateList mDividerColors; private ColorStateList mDividerErrorColors; private boolean mDividerCompoundPadding; private int mDividerPadding; private ColorStateList mSupportColors; private ColorStateList mSupportErrorColors; private int mSupportMaxChars; private CharSequence mSupportHelper; private CharSequence mSupportError; private int mLabelInAnimId; private int mLabelOutAnimId; protected LabelView mLabelView; protected android.widget.EditText mInputView; protected LabelView mSupportView; private DividerDrawable mDivider; private TextView.OnSelectionChangedListener mOnSelectionChangedListener; private boolean mIsRtl; public EditText(Context context) { super(context); } public EditText(Context context, AttributeSet attrs) { super(context, attrs); } public EditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @SuppressWarnings("deprecation") @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override protected void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { mLabelEnable = false; mLabelVisible = false; mSupportMode = SUPPORT_MODE_NONE; mAutoCompleteMode = AUTOCOMPLETE_MODE_NONE; mDividerCompoundPadding = true; mDividerPadding = -1; mIsRtl = false; super.init(context, attrs, defStyleAttr, defStyleRes); if (isInEditMode()) applyStyle(R.style.Material_Widget_EditText); } private LabelView getLabelView() { if (mLabelView == null) { mLabelView = new LabelView(getContext()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) mLabelView.setTextDirection(mIsRtl ? TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR); mLabelView.setGravity(Gravity.START); mLabelView.setSingleLine(true); } return mLabelView; } private LabelView getSupportView() { if (mSupportView == null) mSupportView = new LabelView(getContext()); return mSupportView; } private boolean needCreateInputView(int autoCompleteMode) { if (mInputView == null) return true; switch (autoCompleteMode) { case AUTOCOMPLETE_MODE_NONE: return !(mInputView instanceof InternalEditText); case AUTOCOMPLETE_MODE_SINGLE: return !(mInputView instanceof InternalAutoCompleteTextView); case AUTOCOMPLETE_MODE_MULTI: return !(mInputView instanceof InternalMultiAutoCompleteTextView); default: return false; } } @Override protected void applyStyle(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super.applyStyle(context, attrs, defStyleAttr, defStyleRes); CharSequence text = mInputView == null ? null : mInputView.getText(); removeAllViews(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.EditText, defStyleAttr, defStyleRes); int labelPadding = -1; int labelTextSize = -1; ColorStateList labelTextColor = null; int supportPadding = -1; int supportTextSize = -1; ColorStateList supportColors = null; ColorStateList supportErrorColors = null; String supportHelper = null; String supportError = null; ColorStateList dividerColors = null; ColorStateList dividerErrorColors = null; int dividerHeight = -1; int dividerPadding = -1; int dividerAnimDuration = -1; mAutoCompleteMode = a.getInteger(R.styleable.EditText_et_autoCompleteMode, mAutoCompleteMode); if (needCreateInputView(mAutoCompleteMode)) { switch (mAutoCompleteMode) { case AUTOCOMPLETE_MODE_SINGLE: mInputView = new InternalAutoCompleteTextView(context, attrs, defStyleAttr); break; case AUTOCOMPLETE_MODE_MULTI: mInputView = new InternalMultiAutoCompleteTextView(context, attrs, defStyleAttr); break; default: mInputView = new InternalEditText(context, attrs, defStyleAttr); break; } ViewUtil.applyFont(mInputView, attrs, defStyleAttr, defStyleRes); if (text != null) mInputView.setText(text); mInputView.addTextChangedListener(new InputTextWatcher()); if (mDivider != null) { mDivider.setAnimEnable(false); ViewUtil.setBackground(mInputView, mDivider); mDivider.setAnimEnable(true); } } else ViewUtil.applyStyle(mInputView, attrs, defStyleAttr, defStyleRes); mInputView.setVisibility(View.VISIBLE); mInputView.setFocusableInTouchMode(true); for (int i = 0, count = a.getIndexCount(); i < count; i++) { int attr = a.getIndex(i); if (attr == R.styleable.EditText_et_labelEnable) mLabelEnable = a.getBoolean(attr, false); else if (attr == R.styleable.EditText_et_labelPadding) labelPadding = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.EditText_et_labelTextSize) labelTextSize = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.EditText_et_labelTextColor) labelTextColor = a.getColorStateList(attr); else if (attr == R.styleable.EditText_et_labelTextAppearance) getLabelView().setTextAppearance(context, a.getResourceId(attr, 0)); else if (attr == R.styleable.EditText_et_labelEllipsize) { int labelEllipsize = a.getInteger(attr, 0); switch (labelEllipsize) { case 1: getLabelView().setEllipsize(TruncateAt.START); break; case 2: getLabelView().setEllipsize(TruncateAt.MIDDLE); break; case 3: getLabelView().setEllipsize(TruncateAt.END); break; case 4: getLabelView().setEllipsize(TruncateAt.MARQUEE); break; default: getLabelView().setEllipsize(TruncateAt.END); break; } } else if (attr == R.styleable.EditText_et_labelInAnim) mLabelInAnimId = a.getResourceId(attr, 0); else if (attr == R.styleable.EditText_et_labelOutAnim) mLabelOutAnimId = a.getResourceId(attr, 0); else if (attr == R.styleable.EditText_et_supportMode) mSupportMode = a.getInteger(attr, 0); else if (attr == R.styleable.EditText_et_supportPadding) supportPadding = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.EditText_et_supportTextSize) supportTextSize = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.EditText_et_supportTextColor) supportColors = a.getColorStateList(attr); else if (attr == R.styleable.EditText_et_supportTextErrorColor) supportErrorColors = a.getColorStateList(attr); else if (attr == R.styleable.EditText_et_supportTextAppearance) getSupportView().setTextAppearance(context, a.getResourceId(attr, 0)); else if (attr == R.styleable.EditText_et_supportEllipsize) { int supportEllipsize = a.getInteger(attr, 0); switch (supportEllipsize) { case 1: getSupportView().setEllipsize(TruncateAt.START); break; case 2: getSupportView().setEllipsize(TruncateAt.MIDDLE); break; case 3: getSupportView().setEllipsize(TruncateAt.END); break; case 4: getSupportView().setEllipsize(TruncateAt.MARQUEE); break; default: getSupportView().setEllipsize(TruncateAt.END); break; } } else if (attr == R.styleable.EditText_et_supportMaxLines) getSupportView().setMaxLines(a.getInteger(attr, 0)); else if (attr == R.styleable.EditText_et_supportLines) getSupportView().setLines(a.getInteger(attr, 0)); else if (attr == R.styleable.EditText_et_supportSingleLine) getSupportView().setSingleLine(a.getBoolean(attr, false)); else if (attr == R.styleable.EditText_et_supportMaxChars) mSupportMaxChars = a.getInteger(attr, 0); else if (attr == R.styleable.EditText_et_helper) supportHelper = a.getString(attr); else if (attr == R.styleable.EditText_et_error) supportError = a.getString(attr); else if (attr == R.styleable.EditText_et_inputId) mInputView.setId(a.getResourceId(attr, 0)); else if (attr == R.styleable.EditText_et_dividerColor) dividerColors = a.getColorStateList(attr); else if (attr == R.styleable.EditText_et_dividerErrorColor) dividerErrorColors = a.getColorStateList(attr); else if (attr == R.styleable.EditText_et_dividerHeight) dividerHeight = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.EditText_et_dividerPadding) dividerPadding = a.getDimensionPixelSize(attr, 0); else if (attr == R.styleable.EditText_et_dividerAnimDuration) dividerAnimDuration = a.getInteger(attr, 0); else if (attr == R.styleable.EditText_et_dividerCompoundPadding) mDividerCompoundPadding = a.getBoolean(attr, true); } a.recycle(); if (mInputView.getId() == 0) mInputView.setId(ViewUtil.generateViewId()); if (mDivider == null) { mDividerColors = dividerColors; mDividerErrorColors = dividerErrorColors; if (mDividerColors == null) { int[][] states = new int[][] { new int[] { -android.R.attr.state_focused }, new int[] { android.R.attr.state_focused, android.R.attr.state_enabled }, }; int[] colors = new int[] { ThemeUtil.colorControlNormal(context, 0xFF000000), ThemeUtil.colorControlActivated(context, 0xFF000000), }; mDividerColors = new ColorStateList(states, colors); } if (mDividerErrorColors == null) mDividerErrorColors = ColorStateList.valueOf(ThemeUtil.colorAccent(context, 0xFFFF0000)); if (dividerHeight < 0) dividerHeight = 0; if (dividerPadding < 0) dividerPadding = 0; if (dividerAnimDuration < 0) dividerAnimDuration = context.getResources().getInteger(android.R.integer.config_shortAnimTime); mDividerPadding = dividerPadding; mInputView.setPadding(0, 0, 0, mDividerPadding + dividerHeight); mDivider = new DividerDrawable(dividerHeight, mDividerCompoundPadding ? mInputView.getTotalPaddingLeft() : 0, mDividerCompoundPadding ? mInputView.getTotalPaddingRight() : 0, mDividerColors, dividerAnimDuration); mDivider.setInEditMode(isInEditMode()); mDivider.setAnimEnable(false); ViewUtil.setBackground(mInputView, mDivider); mDivider.setAnimEnable(true); } else { if (dividerHeight >= 0 || dividerPadding >= 0) { if (dividerHeight < 0) dividerHeight = mDivider.getDividerHeight(); if (dividerPadding >= 0) mDividerPadding = dividerPadding; mInputView.setPadding(0, 0, 0, mDividerPadding + dividerHeight); mDivider.setDividerHeight(dividerHeight); mDivider.setPadding(mDividerCompoundPadding ? mInputView.getTotalPaddingLeft() : 0, mDividerCompoundPadding ? mInputView.getTotalPaddingRight() : 0); } if (dividerColors != null) mDividerColors = dividerColors; if (dividerErrorColors != null) mDividerErrorColors = dividerErrorColors; mDivider.setColor(getError() == null ? mDividerColors : mDividerErrorColors); if (dividerAnimDuration >= 0) mDivider.setAnimationDuration(dividerAnimDuration); } if (labelPadding >= 0) getLabelView().setPadding(mDivider.getPaddingLeft(), 0, mDivider.getPaddingRight(), labelPadding); if (labelTextSize >= 0) getLabelView().setTextSize(TypedValue.COMPLEX_UNIT_PX, labelTextSize); if (labelTextColor != null) getLabelView().setTextColor(labelTextColor); if (mLabelEnable) { mLabelVisible = true; getLabelView().setText(mInputView.getHint()); addView(getLabelView(), 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); setLabelVisible(!TextUtils.isEmpty(mInputView.getText().toString()), false); } if (supportTextSize >= 0) getSupportView().setTextSize(TypedValue.COMPLEX_UNIT_PX, supportTextSize); if (supportColors != null) mSupportColors = supportColors; else if (mSupportColors == null) mSupportColors = context.getResources().getColorStateList(R.color.abc_secondary_text_material_light); if (supportErrorColors != null) mSupportErrorColors = supportErrorColors; else if (mSupportErrorColors == null) mSupportErrorColors = ColorStateList.valueOf(ThemeUtil.colorAccent(context, 0xFFFF0000)); if (supportPadding >= 0) getSupportView().setPadding(mDivider.getPaddingLeft(), supportPadding, mDivider.getPaddingRight(), 0); if (supportHelper == null && supportError == null) getSupportView().setTextColor(getError() == null ? mSupportColors : mSupportErrorColors); else if (supportHelper != null) setHelper(supportHelper); else setError(supportError); if (mSupportMode != SUPPORT_MODE_NONE) { switch (mSupportMode) { case SUPPORT_MODE_CHAR_COUNTER: getSupportView().setGravity(Gravity.END); updateCharCounter(mInputView.getText().length()); break; case SUPPORT_MODE_HELPER: case SUPPORT_MODE_HELPER_WITH_ERROR: getSupportView().setGravity(GravityCompat.START); break; } addView(getSupportView(), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } addView(mInputView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); requestLayout(); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @Override public void onRtlPropertiesChanged(int layoutDirection) { boolean rtl = layoutDirection == LAYOUT_DIRECTION_RTL; if (mIsRtl != rtl) { mIsRtl = rtl; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { if (mLabelView != null) mLabelView.setTextDirection(mIsRtl ? TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR); if (mSupportView != null) mSupportView.setTextDirection(mIsRtl ? TEXT_DIRECTION_RTL : TEXT_DIRECTION_LTR); } requestLayout(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int tempWidthSpec = widthMode == MeasureSpec.UNSPECIFIED ? widthMeasureSpec : MeasureSpec.makeMeasureSpec(widthSize - getPaddingLeft() - getPaddingRight(), widthMode); int tempHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int labelWidth = 0; int labelHeight = 0; int inputWidth = 0; int inputHeight = 0; int supportWidth = 0; int supportHeight = 0; boolean measureLabelView = mLabelView != null && mLabelView.getLayoutParams() != null; boolean measureSupportView = mSupportView != null && mSupportView.getLayoutParams() != null; if (measureLabelView) { mLabelView.measure(tempWidthSpec, tempHeightSpec); labelWidth = mLabelView.getMeasuredWidth(); labelHeight = mLabelView.getMeasuredHeight(); } mInputView.measure(tempWidthSpec, tempHeightSpec); inputWidth = mInputView.getMeasuredWidth(); inputHeight = mInputView.getMeasuredHeight(); if (measureSupportView) { mSupportView.measure(tempWidthSpec, tempHeightSpec); supportWidth = mSupportView.getMeasuredWidth(); supportHeight = mSupportView.getMeasuredHeight(); } int width = 0; int height = 0; switch (widthMode) { case MeasureSpec.UNSPECIFIED: width = Math.max(labelWidth, Math.max(inputWidth, supportWidth)) + getPaddingLeft() + getPaddingRight(); break; case MeasureSpec.AT_MOST: width = Math.min(widthSize, Math.max(labelWidth, Math.max(inputWidth, supportWidth)) + getPaddingLeft() + getPaddingRight()); break; case MeasureSpec.EXACTLY: width = widthSize; break; } inputWidth = width - getPaddingLeft() - getPaddingRight(); tempWidthSpec = MeasureSpec.makeMeasureSpec(inputWidth, MeasureSpec.EXACTLY); if (measureLabelView && mLabelView.getWidth() != inputWidth) { mLabelView.measure(tempWidthSpec, tempHeightSpec); labelHeight = mLabelView.getMeasuredHeight(); } if (measureSupportView && mSupportView.getWidth() != inputWidth) { mSupportView.measure(tempWidthSpec, tempHeightSpec); supportHeight = mSupportView.getMeasuredHeight(); } switch (heightMode) { case MeasureSpec.UNSPECIFIED: height = labelHeight + inputHeight + supportHeight + getPaddingTop() + getPaddingBottom(); break; case MeasureSpec.AT_MOST: height = Math.min(heightSize, labelHeight + inputHeight + supportHeight + getPaddingTop() + getPaddingBottom()); break; case MeasureSpec.EXACTLY: height = heightSize; break; } setMeasuredDimension(width, height); inputHeight = height - labelHeight - supportHeight - getPaddingTop() - getPaddingBottom(); if (mInputView.getMeasuredWidth() != inputWidth || mInputView.getMeasuredHeight() != inputHeight) mInputView.measure(tempWidthSpec, MeasureSpec.makeMeasureSpec(inputHeight, MeasureSpec.EXACTLY)); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childLeft = getPaddingLeft(); int childRight = r - l - getPaddingRight(); int childTop = getPaddingTop(); int childBottom = b - t - getPaddingBottom(); if (mLabelView != null) { mLabelView.layout(childLeft, childTop, childRight, childTop + mLabelView.getMeasuredHeight()); childTop += mLabelView.getMeasuredHeight(); } if (mSupportView != null) { mSupportView.layout(childLeft, childBottom - mSupportView.getMeasuredHeight(), childRight, childBottom); childBottom -= mSupportView.getMeasuredHeight(); } mInputView.layout(childLeft, childTop, childRight, childBottom); } /** * Set the helper text of this EditText. Only work with support mode {@link #SUPPORT_MODE_HELPER} and {@link #SUPPORT_MODE_HELPER_WITH_ERROR}. * @param helper The helper text. */ public void setHelper(CharSequence helper) { mSupportHelper = helper; setError(mSupportError); } /** * @return The helper text of this EditText. */ public CharSequence getHelper() { return mSupportHelper; } /** * Set the error text of this EditText. Only work with support mode {@link #SUPPORT_MODE_HELPER} and {@link #SUPPORT_MODE_HELPER_WITH_ERROR}. * @param error The error text. Set null will clear the error. */ public void setError(CharSequence error) { mSupportError = error; if (mSupportMode != SUPPORT_MODE_HELPER && mSupportMode != SUPPORT_MODE_HELPER_WITH_ERROR) return; if (mSupportError != null) { getSupportView().setTextColor(mSupportErrorColors); mDivider.setColor(mDividerErrorColors); getSupportView().setText(mSupportMode == SUPPORT_MODE_HELPER ? mSupportError : TextUtils.concat(mSupportHelper, ", ", mSupportError)); } else { getSupportView().setTextColor(mSupportColors); mDivider.setColor(mDividerColors); getSupportView().setText(mSupportHelper); } } /** * @return The error text of this EditText. */ public CharSequence getError() { return mSupportError; } /** * Clear the error text. Only work with support mode {@link #SUPPORT_MODE_HELPER} and {@link #SUPPORT_MODE_HELPER_WITH_ERROR}. */ public void clearError() { setError(null); } private void updateCharCounter(int count) { if (count == 0) { getSupportView().setTextColor(mSupportColors); mDivider.setColor(mDividerColors); getSupportView().setText(null); } else { if (mSupportMaxChars > 0) { getSupportView().setTextColor(count > mSupportMaxChars ? mSupportErrorColors : mSupportColors); mDivider.setColor(count > mSupportMaxChars ? mDividerErrorColors : mDividerColors); getSupportView().setText(count + " / " + mSupportMaxChars); } else getSupportView().setText(String.valueOf(count)); } } private void setLabelVisible(boolean visible, boolean animation) { if (!mLabelEnable || mLabelVisible == visible) return; mLabelVisible = visible; if (animation) { if (mLabelVisible) { if (mLabelInAnimId != 0) { Animation anim = AnimationUtils.loadAnimation(getContext(), mLabelInAnimId); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mLabelView.setVisibility(View.VISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { } }); mLabelView.clearAnimation(); mLabelView.startAnimation(anim); } else mLabelView.setVisibility(View.VISIBLE); } else { if (mLabelOutAnimId != 0) { Animation anim = AnimationUtils.loadAnimation(getContext(), mLabelOutAnimId); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { mLabelView.setVisibility(View.VISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mLabelView.setVisibility(View.INVISIBLE); } }); mLabelView.clearAnimation(); mLabelView.startAnimation(anim); } else mLabelView.setVisibility(View.INVISIBLE); } } else mLabelView.setVisibility(mLabelVisible ? View.VISIBLE : View.INVISIBLE); } /* protected method of AutoCompleteTextView */ /** * <p>Converts the selected item from the drop down list into a sequence * of character that can be used in the edit box.</p> * * @param selectedItem the item selected by the user for completion * * @return a sequence of characters representing the selected suggestion */ protected CharSequence convertSelectionToString(Object selectedItem) { switch (mAutoCompleteMode) { case AUTOCOMPLETE_MODE_SINGLE: return ((InternalAutoCompleteTextView) mInputView).superConvertSelectionToString(selectedItem); case AUTOCOMPLETE_MODE_MULTI: return ((InternalMultiAutoCompleteTextView) mInputView).superConvertSelectionToString(selectedItem); default: return null; } } /** * <p>Starts filtering the content of the drop down list. The filtering * pattern is the content of the edit box. Subclasses should override this * method to filter with a different pattern, for instance a substring of * <code>text</code>.</p> * * @param text the filtering pattern * @param keyCode the last character inserted in the edit box; beware that * this will be null when text is being added through a soft input method. */ protected void performFiltering(CharSequence text, int keyCode) { switch (mAutoCompleteMode) { case AUTOCOMPLETE_MODE_SINGLE: ((InternalAutoCompleteTextView) mInputView).superPerformFiltering(text, keyCode); break; case AUTOCOMPLETE_MODE_MULTI: ((InternalMultiAutoCompleteTextView) mInputView).superPerformFiltering(text, keyCode); break; } } /** * <p>Performs the text completion by replacing the current text by the * selected item. Subclasses should override this method to avoid replacing * the whole content of the edit box.</p> * * @param text the selected suggestion in the drop down list */ protected void replaceText(CharSequence text) { switch (mAutoCompleteMode) { case AUTOCOMPLETE_MODE_SINGLE: ((InternalAutoCompleteTextView) mInputView).superReplaceText(text); break; case AUTOCOMPLETE_MODE_MULTI: ((InternalMultiAutoCompleteTextView) mInputView).superReplaceText(text); break; } } /** * Returns the Filter obtained from {@link Filterable#getFilter}, * or <code>null</code> if {@link #setAdapter} was not called with * a Filterable. */ protected Filter getFilter() { switch (mAutoCompleteMode) { case AUTOCOMPLETE_MODE_SINGLE: return ((InternalAutoCompleteTextView) mInputView).superGetFilter(); case AUTOCOMPLETE_MODE_MULTI: return ((InternalMultiAutoCompleteTextView) mInputView).superGetFilter(); default: return null; } } /** * <p>Starts filtering the content of the drop down list. The filtering * pattern is the specified range of text from the edit box. Subclasses may * override this method to filter with a different pattern, for * instance a smaller substring of <code>text</code>.</p> */ protected void performFiltering(CharSequence text, int start, int end, int keyCode) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_MULTI) ((InternalMultiAutoCompleteTextView) mInputView).superPerformFiltering(text, start, end, keyCode); } /* public method of AutoCompleteTextView */ /** * <p>Sets the optional hint text that is displayed at the bottom of the * the matching list. This can be used as a cue to the user on how to * best use the list, or to provide extra information.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param hint the text to be displayed to the user * * @see #getCompletionHint() * * @attr ref android.R.styleable#AutoCompleteTextView_completionHint */ public void setCompletionHint(CharSequence hint) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setCompletionHint(hint); } /** * Gets the optional hint text displayed at the bottom of the the matching list. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return The hint text, if any * * @see #setCompletionHint(CharSequence) * * @attr ref android.R.styleable#AutoCompleteTextView_completionHint */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public CharSequence getCompletionHint() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return null; return ((AutoCompleteTextView) mInputView).getCompletionHint(); } /** * <p>Returns the current width for the auto-complete drop down list. This can * be a fixed width, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill the screen, or * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the width for the drop down list * * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth */ public int getDropDownWidth() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return 0; return ((AutoCompleteTextView) mInputView).getDropDownWidth(); } /** * <p>Sets the current width for the auto-complete drop down list. This can * be a fixed width, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill the screen, or * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param width the width to use * * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth */ public void setDropDownWidth(int width) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setDropDownWidth(width); } /** * <p>Returns the current height for the auto-complete drop down list. This can * be a fixed height, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height * of the drop down's content.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the height for the drop down list * * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight */ public int getDropDownHeight() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return 0; return ((AutoCompleteTextView) mInputView).getDropDownHeight(); } /** * <p>Sets the current height for the auto-complete drop down list. This can * be a fixed height, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height * of the drop down's content.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param height the height to use * * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight */ public void setDropDownHeight(int height) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setDropDownHeight(height); } /** * <p>Returns the id for the view that the auto-complete drop down list is anchored to.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the view's id, or {@link View#NO_ID} if none specified * * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor */ public int getDropDownAnchor() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return 0; return ((AutoCompleteTextView) mInputView).getDropDownAnchor(); } /** * <p>Sets the view to which the auto-complete drop down list should anchor. The view * corresponding to this id will not be loaded until the next time it is needed to avoid * loading a view which is not yet instantiated.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param id the id to anchor the drop down list view to * * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor */ public void setDropDownAnchor(int id) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setDropDownAnchor(id); } /** * <p>Gets the background of the auto-complete drop-down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the background drawable * * @attr ref android.R.styleable#PopupWindow_popupBackground */ public Drawable getDropDownBackground() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return null; return ((AutoCompleteTextView) mInputView).getDropDownBackground(); } /** * <p>Sets the background of the auto-complete drop-down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param d the drawable to set as the background * * @attr ref android.R.styleable#PopupWindow_popupBackground */ public void setDropDownBackgroundDrawable(Drawable d) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setDropDownBackgroundDrawable(d); } /** * <p>Sets the background of the auto-complete drop-down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param id the id of the drawable to set as the background * * @attr ref android.R.styleable#PopupWindow_popupBackground */ public void setDropDownBackgroundResource(int id) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setDropDownBackgroundResource(id); } /** * <p>Sets the vertical offset used for the auto-complete drop-down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param offset the vertical offset * * @attr ref android.R.styleable#ListPopupWindow_dropDownVerticalOffset */ public void setDropDownVerticalOffset(int offset) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setDropDownVerticalOffset(offset); } /** * <p>Gets the vertical offset used for the auto-complete drop-down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the vertical offset * * @attr ref android.R.styleable#ListPopupWindow_dropDownVerticalOffset */ public int getDropDownVerticalOffset() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return 0; return ((AutoCompleteTextView) mInputView).getDropDownVerticalOffset(); } /** * <p>Sets the horizontal offset used for the auto-complete drop-down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param offset the horizontal offset * * @attr ref android.R.styleable#ListPopupWindow_dropDownHorizontalOffset */ public void setDropDownHorizontalOffset(int offset) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setDropDownHorizontalOffset(offset); } /** * <p>Gets the horizontal offset used for the auto-complete drop-down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the horizontal offset * * @attr ref android.R.styleable#ListPopupWindow_dropDownHorizontalOffset */ public int getDropDownHorizontalOffset() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return 0; return ((AutoCompleteTextView) mInputView).getDropDownHorizontalOffset(); } /** * <p>Returns the number of characters the user must type before the drop * down list is shown.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the minimum number of characters to type to show the drop down * * @see #setThreshold(int) * * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold */ public int getThreshold() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return 0; return ((AutoCompleteTextView) mInputView).getThreshold(); } /** * <p>Specifies the minimum number of characters the user has to type in the * edit box before the drop down list is shown.</p> * * <p>When <code>threshold</code> is less than or equals 0, a threshold of * 1 is applied.</p> * * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param threshold the number of characters to type before the drop down * is shown * * @see #getThreshold() * * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold */ public void setThreshold(int threshold) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setThreshold(threshold); } /** * <p>Sets the listener that will be notified when the user clicks an item * in the drop down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param l the item click listener */ public void setOnItemClickListener(AdapterView.OnItemClickListener l) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setOnItemClickListener(l); } /** * <p>Sets the listener that will be notified when the user selects an item * in the drop down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param l the item selected listener */ public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener l) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setOnItemSelectedListener(l); } /** * <p>Returns the listener that is notified whenever the user clicks an item * in the drop down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the item click listener */ public AdapterView.OnItemClickListener getOnItemClickListener() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return null; return ((AutoCompleteTextView) mInputView).getOnItemClickListener(); } /** * <p>Returns the listener that is notified whenever the user selects an * item in the drop down list.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the item selected listener */ public AdapterView.OnItemSelectedListener getOnItemSelectedListener() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return null; return ((AutoCompleteTextView) mInputView).getOnItemSelectedListener(); } /** * <p>Returns a filterable list adapter used for auto completion.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return a data adapter used for auto completion */ public ListAdapter getAdapter() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return null; return ((AutoCompleteTextView) mInputView).getAdapter(); } /** * <p>Changes the list of data used for auto completion. The provided list * must be a filterable list adapter.</p> * * <p>The caller is still responsible for managing any resources used by the adapter. * Notably, when the AutoCompleteTextView is closed or released, the adapter is not notified. * A common case is the use of {@link CursorAdapter}, which * contains a {@link android.database.Cursor} that must be closed. This can be done * automatically (see * {@link android.app.Activity#startManagingCursor(android.database.Cursor) * startManagingCursor()}), * or by manually closing the cursor when the AutoCompleteTextView is dismissed.</p> * * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param adapter the adapter holding the auto completion data * * @see #getAdapter() * @see Filterable * @see ListAdapter */ public <T extends ListAdapter & Filterable> void setAdapter(T adapter) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setAdapter(adapter); } /** * Returns <code>true</code> if the amount of text in the field meets * or exceeds the {@link #getThreshold} requirement. You can override * this to impose a different standard for when filtering will be * triggered. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> */ public boolean enoughToFilter() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return false; return ((AutoCompleteTextView) mInputView).enoughToFilter(); } /** * <p>Indicates whether the popup menu is showing.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return true if the popup menu is showing, false otherwise */ public boolean isPopupShowing() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return false; return ((AutoCompleteTextView) mInputView).isPopupShowing(); } /** * <p>Clear the list selection. This may only be temporary, as user input will often bring * it back. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> */ public void clearListSelection() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).clearListSelection(); } /** * Set the position of the dropdown view selection. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param position The position to move the selector to. */ public void setListSelection(int position) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setListSelection(position); } /** * Get the position of the dropdown view selection, if there is one. Returns * {@link ListView#INVALID_POSITION ListView.INVALID_POSITION} if there is no dropdown or if * there is no selection. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @return the position of the current selection, if there is one, or * {@link ListView#INVALID_POSITION ListView.INVALID_POSITION} if not. * * @see ListView#getSelectedItemPosition() */ public int getListSelection() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return 0; return ((AutoCompleteTextView) mInputView).getListSelection(); } /** * <p>Performs the text completion by converting the selected item from * the drop down list into a string, replacing the text box's content with * this string and finally dismissing the drop down menu.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> */ public void performCompletion() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).performCompletion(); } /** * Identifies whether the view is currently performing a text completion, so subclasses * can decide whether to respond to text changed events. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> */ public boolean isPerformingCompletion() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return false; return ((AutoCompleteTextView) mInputView).isPerformingCompletion(); } /** <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> */ public void onFilterComplete(int count) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) ((InternalAutoCompleteTextView) mInputView).superOnFilterComplete(count); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_MULTI) ((InternalMultiAutoCompleteTextView) mInputView).superOnFilterComplete(count); } /** * <p>Closes the drop down if present on screen.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> */ public void dismissDropDown() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).dismissDropDown(); } /** * <p>Displays the drop down on screen.</p> * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> */ public void showDropDown() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).showDropDown(); } /** * Sets the validator used to perform text validation. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @param validator The validator used to validate the text entered in this widget. * * @see #getValidator() * @see #performValidation() */ public void setValidator(AutoCompleteTextView.Validator validator) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).setValidator(validator); } /** * Returns the Validator set with {@link #setValidator}, * or <code>null</code> if it was not set. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @see #setValidator(AutoCompleteTextView.Validator) * @see #performValidation() */ public AutoCompleteTextView.Validator getValidator() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return null; return ((AutoCompleteTextView) mInputView).getValidator(); } /** * If a validator was set on this view and the current string is not valid, * ask the validator to fix it. * <p>Only work when autoComplete mode is {@link #AUTOCOMPLETE_MODE_SINGLE} or {@link #AUTOCOMPLETE_MODE_MULTI}</p> * * @see #getValidator() * @see #setValidator(AutoCompleteTextView.Validator) */ public void performValidation() { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return; ((AutoCompleteTextView) mInputView).performValidation(); } /** * Sets the Tokenizer that will be used to determine the relevant * range of the text where the user is typing. * <p>Only work when autoCompleMode is AUTOCOMPLETE_MODE_MULTI</p> */ public void setTokenizer(MultiAutoCompleteTextView.Tokenizer t) { if (mAutoCompleteMode != AUTOCOMPLETE_MODE_MULTI) return; ((MultiAutoCompleteTextView) mInputView).setTokenizer(t); } /* public method of EditText */ @Override public void setEnabled(boolean enabled) { mInputView.setEnabled(enabled); } /** * Convenience for {@link android.text.Selection#extendSelection}. */ public void extendSelection(int index) { mInputView.extendSelection(index); } public Editable getText() { return mInputView.getText(); } /** * Convenience for {@link android.text.Selection#selectAll}. */ public void selectAll() { mInputView.selectAll(); } /** * Causes words in the text that are longer than the view is wide * to be ellipsized instead of broken in the middle. You may also * want to {@link #setSingleLine} or {@link #setHorizontallyScrolling} * to constrain the text to a single line. Use <code>null</code> * to turn off ellipsizing. * * If {@link #setMaxLines} has been used to set two or more lines, * only {@link TruncateAt#END} and * {@link TruncateAt#MARQUEE} are supported * (other ellipsizing types will not do anything). * * @attr ref android.R.styleable#TextView_ellipsize */ public void setEllipsize(TruncateAt ellipsis) { mInputView.setEllipsize(ellipsis); } /** * Convenience for {@link android.text.Selection#setSelection(Spannable, int)}. */ public void setSelection(int index) { mInputView.setSelection(index); } /** * Convenience for {@link android.text.Selection#setSelection(Spannable, int, int)}. */ public void setSelection(int start, int stop) { mInputView.setSelection(start, stop); } public void setText(CharSequence text, TextView.BufferType type) { mInputView.setText(text, type); } /** * Adds a TextWatcher to the list of those whose methods are called * whenever this TextView's text changes. * <p> * In 1.0, the {@link TextWatcher#afterTextChanged} method was erroneously * not called after {@link #setText} calls. Now, doing {@link #setText} * if there are any text changed listeners forces the buffer type to * Editable if it would not otherwise be and does call this method. */ public void addTextChangedListener(TextWatcher textWatcher) { mInputView.addTextChangedListener(textWatcher); } /** * Convenience method: Append the specified text to the TextView's * display buffer, upgrading it to BufferType.EDITABLE if it was * not already editable. */ public final void append(CharSequence text) { mInputView.append(text); } /** * Convenience method: Append the specified text slice to the TextView's * display buffer, upgrading it to BufferType.EDITABLE if it was * not already editable. */ public void append(CharSequence text, int start, int end) { mInputView.append(text, start, end); } public void beginBatchEdit() { mInputView.beginBatchEdit(); } /** * Move the point, specified by the offset, into the view if it is needed. * This has to be called after layout. Returns true if anything changed. */ public boolean bringPointIntoView(int offset) { return mInputView.bringPointIntoView(offset); } public void cancelLongPress() { mInputView.cancelLongPress(); } /** * Use {@link android.view.inputmethod.BaseInputConnection#removeComposingSpans * BaseInputConnection.removeComposingSpans()} to remove any IME composing * state from this text view. */ public void clearComposingText() { mInputView.clearComposingText(); } @Override public void computeScroll() { mInputView.computeScroll(); } @Override public void debug(int depth) { mInputView.debug(depth); } /** * Returns true, only while processing a touch gesture, if the initial * touch down event caused focus to move to the text view and as a result * its selection changed. Only valid while processing the touch gesture * of interest, in an editable text view. */ public boolean didTouchFocusSelect() { return mInputView.didTouchFocusSelect(); } public void endBatchEdit() { mInputView.endBatchEdit(); } /** * If this TextView contains editable content, extract a portion of it * based on the information in <var>request</var> in to <var>outText</var>. * @return Returns true if the text was successfully extracted, else false. */ public boolean extractText(ExtractedTextRequest request, ExtractedText outText) { return mInputView.extractText(request, outText); } @Override @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public void findViewsWithText(ArrayList<View> outViews, CharSequence searched, int flags) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) mInputView.findViewsWithText(outViews, searched, flags); } /** * Gets the autolink mask of the text. See {@link * android.text.util.Linkify#ALL Linkify.ALL} and peers for * possible values. * * @attr ref android.R.styleable#TextView_autoLink */ public final int getAutoLinkMask() { return mInputView.getAutoLinkMask(); } @Override public int getBaseline() { return mInputView.getBaseline(); } /** * Returns the padding between the compound drawables and the text. * * @attr ref android.R.styleable#TextView_drawablePadding */ public int getCompoundDrawablePadding() { return mInputView.getCompoundDrawablePadding(); } /** * Returns drawables for the left, top, right, and bottom borders. * * @attr ref android.R.styleable#TextView_drawableLeft * @attr ref android.R.styleable#TextView_drawableTop * @attr ref android.R.styleable#TextView_drawableRight * @attr ref android.R.styleable#TextView_drawableBottom */ public Drawable[] getCompoundDrawables() { return mInputView.getCompoundDrawables(); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public Drawable[] getCompoundDrawablesRelative() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) return mInputView.getCompoundDrawablesRelative(); return mInputView.getCompoundDrawables(); } /** * Returns the bottom padding of the view, plus space for the bottom * Drawable if any. */ public int getCompoundPaddingBottom() { return mInputView.getCompoundPaddingBottom(); } /** * Returns the end padding of the view, plus space for the end * Drawable if any. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public int getCompoundPaddingEnd() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) return mInputView.getCompoundPaddingEnd(); return mInputView.getCompoundPaddingRight(); } /** * Returns the left padding of the view, plus space for the left * Drawable if any. */ public int getCompoundPaddingLeft() { return mInputView.getCompoundPaddingLeft(); } /** * Returns the right padding of the view, plus space for the right * Drawable if any. */ public int getCompoundPaddingRight() { return mInputView.getCompoundPaddingRight(); } /** * Returns the start padding of the view, plus space for the start * Drawable if any. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public int getCompoundPaddingStart() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) return mInputView.getCompoundPaddingStart(); return mInputView.getCompoundPaddingLeft(); } /** * Returns the top padding of the view, plus space for the top * Drawable if any. */ public int getCompoundPaddingTop() { return mInputView.getCompoundPaddingTop(); } /** * <p>Return the current color selected to paint the hint text.</p> * * @return Returns the current hint text color. */ public final int getCurrentHintTextColor() { return mInputView.getCurrentHintTextColor(); } /** * <p>Return the current color selected for normal text.</p> * * @return Returns the current text color. */ public final int getCurrentTextColor() { return mInputView.getCurrentTextColor(); } /** * Retrieves the value set in {@link #setCustomSelectionActionModeCallback}. Default is null. * * @return The current custom selection callback. */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) public ActionMode.Callback getCustomSelectionActionModeCallback() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) return mInputView.getCustomSelectionActionModeCallback(); return null; } /** * Return the text the TextView is displaying as an Editable object. If * the text is not editable, null is returned. * * @see #getText */ public Editable getEditableText() { return mInputView.getEditableText(); } /** * Returns where, if anywhere, words that are longer than the view * is wide should be ellipsized. */ public TruncateAt getEllipsize() { return mInputView.getEllipsize(); } /** * Returns the extended bottom padding of the view, including both the * bottom Drawable if any and any extra space to keep more than maxLines * of text from showing. It is only valid to call this after measuring. */ public int getExtendedPaddingBottom() { return mInputView.getExtendedPaddingBottom(); } /** * Returns the extended top padding of the view, including both the * top Drawable if any and any extra space to keep more than maxLines * of text from showing. It is only valid to call this after measuring. */ public int getExtendedPaddingTop() { return mInputView.getExtendedPaddingTop(); } /** * Returns the current list of input filters. * * @attr ref android.R.styleable#TextView_maxLength */ public InputFilter[] getFilters() { return mInputView.getFilters(); } @Override public void getFocusedRect(@NonNull Rect r) { mInputView.getFocusedRect(r); } /** * @return the currently set font feature settings. Default is null. * * @see #setFontFeatureSettings(String) * @see android.graphics.Paint#setFontFeatureSettings */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public String getFontFeatureSettings() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return mInputView.getFontFeatureSettings(); return null; } /** * Return whether this text view is including its entire text contents * in frozen icicles. * * @return Returns true if text is included, false if it isn't. * * @see #setFreezesText */ public boolean getFreezesText() { return mInputView.getFreezesText(); } /** * Returns the horizontal and vertical alignment of this TextView. * * @see Gravity * @attr ref android.R.styleable#TextView_gravity */ public int getGravity() { return mInputView.getGravity(); } /** * @return the color used to display the selection highlight * * @see #setHighlightColor(int) * * @attr ref android.R.styleable#TextView_textColorHighlight */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getHighlightColor() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getHighlightColor(); return 0; } /** * Returns the hint that is displayed when the text of the TextView * is empty. * * @attr ref android.R.styleable#TextView_hint */ public CharSequence getHint() { return mInputView.getHint(); } /** * @return the color of the hint text, for the different states of this TextView. * * @see #setHintTextColor(ColorStateList) * @see #setHintTextColor(int) * @see #setTextColor(ColorStateList) * @see #setLinkTextColor(ColorStateList) * * @attr ref android.R.styleable#TextView_textColorHint */ public final ColorStateList getHintTextColors() { return mInputView.getHintTextColors(); } /** * Get the IME action ID previous set with {@link #setImeActionLabel}. * * @see #setImeActionLabel * @see EditorInfo */ public int getImeActionId() { return mInputView.getImeActionId(); } /** * Get the IME action label previous set with {@link #setImeActionLabel}. * * @see #setImeActionLabel * @see EditorInfo */ public CharSequence getImeActionLabel() { return mInputView.getImeActionLabel(); } /** * Get the type of the IME editor. * * @see #setImeOptions(int) * @see EditorInfo */ public int getImeOptions() { return mInputView.getImeOptions(); } /** * Gets whether the TextView includes extra top and bottom padding to make * room for accents that go above the normal ascent and descent. * * @see #setIncludeFontPadding(boolean) * * @attr ref android.R.styleable#TextView_includeFontPadding */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public boolean getIncludeFontPadding() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && mInputView.getIncludeFontPadding(); } /** * Retrieve the input extras currently associated with the text view, which * can be viewed as well as modified. * * @param create If true, the extras will be created if they don't already * exist. Otherwise, null will be returned if none have been created. * @see #setInputExtras(int) * @see EditorInfo#extras * @attr ref android.R.styleable#TextView_editorExtras */ public Bundle getInputExtras(boolean create) { return mInputView.getInputExtras(create); } /** * Get the type of the editable content. * * @see #setInputType(int) * @see android.text.InputType */ public int getInputType() { return mInputView.getInputType(); } /** * @return the current key listener for this TextView. * This will frequently be null for non-EditText TextViews. * * @attr ref android.R.styleable#TextView_numeric * @attr ref android.R.styleable#TextView_digits * @attr ref android.R.styleable#TextView_phoneNumber * @attr ref android.R.styleable#TextView_inputMethod * @attr ref android.R.styleable#TextView_capitalize * @attr ref android.R.styleable#TextView_autoText */ public final KeyListener getKeyListener() { return mInputView.getKeyListener(); } /** * @return the Layout that is currently being used to display the text. * This can be null if the text or width has recently changes. */ public final Layout getLayout() { return mInputView.getLayout(); } /** * @return the extent by which text is currently being letter-spaced. * This will normally be 0. * * @see #setLetterSpacing(float) * @see android.graphics.Paint#setLetterSpacing */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public float getLetterSpacing() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? mInputView.getLetterSpacing() : 0; } /** * Return the baseline for the specified line (0...getLineCount() - 1) * If bounds is not null, return the top, left, right, bottom extents * of the specified line in it. If the internal Layout has not been built, * return 0 and set bounds to (0, 0, 0, 0) * @param line which line to examine (0..getLineCount() - 1) * @param bounds Optional. If not null, it returns the extent of the line * @return the Y-coordinate of the baseline */ public int getLineBounds(int line, Rect bounds) { return mInputView.getLineBounds(line, bounds); } /** * Return the number of lines of text, or 0 if the internal Layout has not * been built. */ public int getLineCount() { return mInputView.getLineCount(); } /** * @return the height of one standard line in pixels. Note that markup * within the text can cause individual lines to be taller or shorter * than this height, and the layout may contain additional first- * or last-line padding. */ public int getLineHeight() { return mInputView.getLineHeight(); } /** * Gets the line spacing extra space * * @return the extra space that is added to the height of each lines of this TextView. * * @see #setLineSpacing(float, float) * @see #getLineSpacingMultiplier() * * @attr ref android.R.styleable#TextView_lineSpacingExtra */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public float getLineSpacingExtra() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getLineSpacingExtra(); return 0f; } /** * Gets the line spacing multiplier * * @return the value by which each line's height is multiplied to get its actual height. * * @see #setLineSpacing(float, float) * @see #getLineSpacingExtra() * * @attr ref android.R.styleable#TextView_lineSpacingMultiplier */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public float getLineSpacingMultiplier() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getLineSpacingMultiplier(); return 0f; } /** * @return the list of colors used to paint the links in the text, for the different states of * this TextView * * @see #setLinkTextColor(ColorStateList) * @see #setLinkTextColor(int) * * @attr ref android.R.styleable#TextView_textColorLink */ public final ColorStateList getLinkTextColors() { return mInputView.getLinkTextColors(); } /** * Returns whether the movement method will automatically be set to * {@link android.text.method.LinkMovementMethod} if {@link #setAutoLinkMask} has been * set to nonzero and links are detected in {@link #setText}. * The default is true. * * @attr ref android.R.styleable#TextView_linksClickable */ public final boolean getLinksClickable() { return mInputView.getLinksClickable(); } /** * Gets the number of times the marquee animation is repeated. Only meaningful if the * TextView has marquee enabled. * * @return the number of times the marquee animation is repeated. -1 if the animation * repeats indefinitely * * @see #setMarqueeRepeatLimit(int) * * @attr ref android.R.styleable#TextView_marqueeRepeatLimit */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMarqueeRepeatLimit() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMarqueeRepeatLimit(); return -1; } /** * @return the maximum width of the TextView, expressed in ems or -1 if the maximum width * was set in pixels instead (using {@link #setMaxWidth(int)} or {#setWidth(int)}). * * @see #setMaxEms(int) * @see #setEms(int) * * @attr ref android.R.styleable#TextView_maxEms */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMaxEms() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMaxEms(); return -1; } /** * @return the maximum height of this TextView expressed in pixels, or -1 if the maximum * height was set in number of lines instead using {@link #setMaxLines(int) or #setLines(int)}. * * @see #setMaxHeight(int) * * @attr ref android.R.styleable#TextView_maxHeight */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMaxHeight() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMaxHeight(); return -1; } /** * @return the maximum number of lines displayed in this TextView, or -1 if the maximum * height was set in pixels instead using {@link #setMaxHeight(int) or #setDividerHeight(int)}. * * @see #setMaxLines(int) * * @attr ref android.R.styleable#TextView_maxLines */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMaxLines() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMaxLines(); return -1; } /** * @return the maximum width of the TextView, in pixels or -1 if the maximum width * was set in ems instead (using {@link #setMaxEms(int)} or {@link #setEms(int)}). * * @see #setMaxWidth(int) * #setWidth(int) * * @attr ref android.R.styleable#TextView_maxWidth */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMaxWidth() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMaxWidth(); return -1; } /** * @return the minimum width of the TextView, expressed in ems or -1 if the minimum width * was set in pixels instead (using {@link #setMinWidth(int)} or {#setWidth(int)}). * * @see #setMinEms(int) * @see #setEms(int) * * @attr ref android.R.styleable#TextView_minEms */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMinEms() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMinEms(); return -1; } /** * @return the minimum height of this TextView expressed in pixels, or -1 if the minimum * height was set in number of lines instead using {@link #setMinLines(int) or #setLines(int)}. * * @see #setMinHeight(int) * * @attr ref android.R.styleable#TextView_minHeight */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMinHeight() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMinHeight(); return -1; } /** * @return the minimum number of lines displayed in this TextView, or -1 if the minimum * height was set in pixels instead using {@link #setMinHeight(int) or #setDividerHeight(int)}. * * @see #setMinLines(int) * * @attr ref android.R.styleable#TextView_minLines */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMinLines() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMinLines(); return -1; } /** * @return the minimum width of the TextView, in pixels or -1 if the minimum width * was set in ems instead (using {@link #setMinEms(int)} or {@link #setEms(int)}). * * @see #setMinWidth(int) * #setWidth(int) * * @attr ref android.R.styleable#TextView_minWidth */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getMinWidth() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getMinWidth(); return -1; } /** * @return the movement method being used for this TextView. * This will frequently be null for non-EditText TextViews. */ public final MovementMethod getMovementMethod() { return mInputView.getMovementMethod(); } /** * Get the character offset closest to the specified absolute position. A typical use case is to * pass the result of {@link android.view.MotionEvent#getX()} and {@link android.view.MotionEvent#getY()} to this method. * * @param x The horizontal absolute position of a point on screen * @param y The vertical absolute position of a point on screen * @return the character offset for the character whose position is closest to the specified * position. Returns -1 if there is no layout. */ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public int getOffsetForPosition(float x, float y) { if (getLayout() == null) return -1; final int line = getLineAtCoordinate(y); final int offset = getOffsetAtCoordinate(line, x); return offset; } protected float convertToLocalHorizontalCoordinate(float x) { x -= getTotalPaddingLeft(); // Clamp the position to inside of the view. x = Math.max(0.0f, x); x = Math.min(getWidth() - getTotalPaddingRight() - 1, x); x += getScrollX(); return x; } protected int getLineAtCoordinate(float y) { y -= getTotalPaddingTop(); // Clamp the position to inside of the view. y = Math.max(0.0f, y); y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y); y += getScrollY(); return getLayout().getLineForVertical((int) y); } protected int getOffsetAtCoordinate(int line, float x) { x = convertToLocalHorizontalCoordinate(x); return getLayout().getOffsetForHorizontal(line, x); } /** * @return the base paint used for the text. Please use this only to * consult the Paint's properties and not to change them. */ public TextPaint getPaint() { return mInputView.getPaint(); } /** * @return the flags on the Paint being used to display the text. * @see android.graphics.Paint#getFlags */ public int getPaintFlags() { return mInputView.getPaintFlags(); } /** * Get the private type of the content. * * #setPrivateImeOptions(String) * @see EditorInfo#privateImeOptions */ public String getPrivateImeOptions() { return mInputView.getPrivateImeOptions(); } /** * Convenience for {@link android.text.Selection#getSelectionEnd}. */ public int getSelectionEnd() { return mInputView.getSelectionEnd(); } /** * Convenience for {@link android.text.Selection#getSelectionStart}. */ public int getSelectionStart() { return mInputView.getSelectionStart(); } /** * @return the color of the shadow layer * * @see #setShadowLayer(float, float, float, int) * * @attr ref android.R.styleable#TextView_shadowColor */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int getShadowColor() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getShadowColor(); return 0; } /** * @return the horizontal offset of the shadow layer * * @see #setShadowLayer(float, float, float, int) * * @attr ref android.R.styleable#TextView_shadowDx */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public float getShadowDx() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getShadowDx(); return 0; } /** * @return the vertical offset of the shadow layer * * @see #setShadowLayer(float, float, float, int) * * @attr ref android.R.styleable#TextView_shadowDy */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public float getShadowDy() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getShadowDy(); return 0; } /** * Gets the radius of the shadow layer. * * @return the radius of the shadow layer. If 0, the shadow layer is not visible * * @see #setShadowLayer(float, float, float, int) * * @attr ref android.R.styleable#TextView_shadowRadius */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public float getShadowRadius() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return mInputView.getShadowRadius(); return 0; } /** * Returns whether the soft input method will be made visible when this * TextView gets focused. The default is true. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public final boolean getShowSoftInputOnFocus() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return mInputView.getShowSoftInputOnFocus(); return true; } /** * Gets the text colors for the different states (normal, selected, focused) of the TextView. * * @see #setTextColor(ColorStateList) * @see #setTextColor(int) * * @attr ref android.R.styleable#TextView_textColor */ public final ColorStateList getTextColors() { return mInputView.getTextColors(); } /** * Get the default {@link Locale} of the text in this TextView. * @return the default {@link Locale} of the text in this TextView. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public Locale getTextLocale() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) return mInputView.getTextLocale(); return Locale.getDefault(); } /** * @return the extent by which text is currently being stretched * horizontally. This will usually be 1. */ public float getTextScaleX() { return mInputView.getTextScaleX(); } /** * @return the size (in pixels) of the default text size in this TextView. */ public float getTextSize() { return mInputView.getTextSize(); } /** * Returns the total bottom padding of the view, including the bottom * Drawable if any, the extra space to keep more than maxLines * from showing, and the vertical offset for gravity, if any. */ public int getTotalPaddingBottom() { return getPaddingBottom() + mInputView.getTotalPaddingBottom() + (mSupportMode != SUPPORT_MODE_NONE ? mSupportView.getHeight() : 0); } /** * Returns the total end padding of the view, including the end * Drawable if any. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public int getTotalPaddingEnd() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) return getPaddingEnd() + mInputView.getTotalPaddingEnd(); return getTotalPaddingRight(); } /** * Returns the total left padding of the view, including the left * Drawable if any. */ public int getTotalPaddingLeft() { return getPaddingLeft() + mInputView.getTotalPaddingLeft(); } /** * Returns the total right padding of the view, including the right * Drawable if any. */ public int getTotalPaddingRight() { return getPaddingRight() + mInputView.getTotalPaddingRight(); } /** * Returns the total start padding of the view, including the start * Drawable if any. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public int getTotalPaddingStart() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) return getPaddingStart() + mInputView.getTotalPaddingStart(); return getTotalPaddingLeft(); } /** * Returns the total top padding of the view, including the top * Drawable if any, the extra space to keep more than maxLines * from showing, and the vertical offset for gravity, if any. */ public int getTotalPaddingTop() { return getPaddingTop() + mInputView.getTotalPaddingTop() + (mLabelEnable ? mLabelView.getHeight() : 0); } /** * @return the current transformation method for this TextView. * This will frequently be null except for single-line and password * fields. * * @attr ref android.R.styleable#TextView_password * @attr ref android.R.styleable#TextView_singleLine */ public final TransformationMethod getTransformationMethod() { return mInputView.getTransformationMethod(); } /** * @return the current typeface and style in which the text is being * displayed. * * @see #setTypeface(Typeface) * * @attr ref android.R.styleable#TextView_fontFamily * @attr ref android.R.styleable#TextView_typeface * @attr ref android.R.styleable#TextView_textStyle */ public Typeface getTypeface() { return mInputView.getTypeface(); } /** * Returns the list of URLSpans attached to the text * (by {@link android.text.util.Linkify} or otherwise) if any. You can call * {@link URLSpan#getURL} on them to find where they link to * or use {@link android.text.Spanned#getSpanStart} and {@link android.text.Spanned#getSpanEnd} * to find the region of the text they are attached to. */ public URLSpan[] getUrls() { return mInputView.getUrls(); } @Override @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public boolean hasOverlappingRendering() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && mInputView.hasOverlappingRendering(); } /** * Return true iff there is a selection inside this text view. */ public boolean hasSelection() { return mInputView.hasSelection(); } /** * @return whether or not the cursor is visible (assuming this TextView is editable) * * @see #setCursorVisible(boolean) * * @attr ref android.R.styleable#TextView_cursorVisible */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public boolean isCursorVisible() { return Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN || mInputView.isCursorVisible(); } /** * Returns whether this text view is a current input method target. The * default implementation just checks with {@link android.view.inputmethod.InputMethodManager}. */ public boolean isInputMethodTarget() { return mInputView.isInputMethodTarget(); } /** * Return whether or not suggestions are enabled on this TextView. The suggestions are generated * by the IME or by the spell checker as the user types. This is done by adding * {@link android.text.style.SuggestionSpan}s to the text. * * When suggestions are enabled (default), this list of suggestions will be displayed when the * user asks for them on these parts of the text. This value depends on the inputType of this * TextView. * * The class of the input type must be {@link android.text.InputType#TYPE_CLASS_TEXT}. * * In addition, the type variation must be one of * {@link android.text.InputType#TYPE_TEXT_VARIATION_NORMAL}, * {@link android.text.InputType#TYPE_TEXT_VARIATION_EMAIL_SUBJECT}, * {@link android.text.InputType#TYPE_TEXT_VARIATION_LONG_MESSAGE}, * {@link android.text.InputType#TYPE_TEXT_VARIATION_SHORT_MESSAGE} or * {@link android.text.InputType#TYPE_TEXT_VARIATION_WEB_EDIT_TEXT}. * * And finally, the {@link android.text.InputType#TYPE_TEXT_FLAG_NO_SUGGESTIONS} flag must <i>not</i> be set. * * @return true if the suggestions popup window is enabled, based on the inputType. */ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public boolean isSuggestionsEnabled() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && mInputView.isSuggestionsEnabled(); } /** * * Returns the state of the {@code textIsSelectable} flag (See * {@link #setTextIsSelectable setTextIsSelectable()}). Although you have to set this flag * to allow users to select and copy text in a non-editable TextView, the content of an * {@link EditText} can always be selected, independently of the value of this flag. * <p> * * @return True if the text displayed in this TextView can be selected by the user. * * @attr ref android.R.styleable#TextView_textIsSelectable */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) public boolean isTextSelectable() { return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB || mInputView.isTextSelectable(); } /** * Returns the length, in characters, of the text managed by this TextView */ public int length() { return mInputView.length(); } /** * Move the cursor, if needed, so that it is at an offset that is visible * to the user. This will not move the cursor if it represents more than * one character (a selection range). This will only work if the * TextView contains spannable text; otherwise it will do nothing. * * @return True if the cursor was actually moved, false otherwise. */ public boolean moveCursorToVisibleOffset() { return mInputView.moveCursorToVisibleOffset(); } /** * Called by the framework in response to a text completion from * the current input method, provided by it calling * {@link InputConnection#commitCompletion * InputConnection.commitCompletion()}. The default implementation does * nothing; text views that are supporting auto-completion should override * this to do their desired behavior. * * @param text The auto complete text the user has selected. */ public void onCommitCompletion(CompletionInfo text) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) ((InternalEditText) mInputView).superOnCommitCompletion(text); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) ((InternalAutoCompleteTextView) mInputView).superOnCommitCompletion(text); else ((InternalMultiAutoCompleteTextView) mInputView).superOnCommitCompletion(text); } /** * Called by the framework in response to a text auto-correction (such as fixing a typo using a * a dictionnary) from the current input method, provided by it calling * {@link InputConnection#commitCorrection} InputConnection.commitCorrection()}. The default * implementation flashes the background of the corrected word to provide feedback to the user. * * @param info The auto correct info about the text that was corrected. */ public void onCommitCorrection(CorrectionInfo info) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) ((InternalEditText) mInputView).superOnCommitCorrection(info); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) ((InternalAutoCompleteTextView) mInputView).superOnCommitCorrection(info); else ((InternalMultiAutoCompleteTextView) mInputView).superOnCommitCorrection(info); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return ((InternalEditText) mInputView).superOnCreateInputConnection(outAttrs); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) return ((InternalAutoCompleteTextView) mInputView).superOnCreateInputConnection(outAttrs); else return ((InternalMultiAutoCompleteTextView) mInputView).superOnCreateInputConnection(outAttrs); } /** * Called when an attached input method calls * {@link InputConnection#performEditorAction(int) * InputConnection.performEditorAction()} * for this text view. The default implementation will call your action * listener supplied to {@link #setOnEditorActionListener}, or perform * a standard operation for {@link EditorInfo#IME_ACTION_NEXT * EditorInfo.IME_ACTION_NEXT}, {@link EditorInfo#IME_ACTION_PREVIOUS * EditorInfo.IME_ACTION_PREVIOUS}, or {@link EditorInfo#IME_ACTION_DONE * EditorInfo.IME_ACTION_DONE}. * * <p>For backwards compatibility, if no IME options have been set and the * text view would not normally advance focus on enter, then * the NEXT and DONE actions received here will be turned into an enter * key down/up pair to go through the normal key handling. * * @param actionCode The code of the action being performed. * * @see #setOnEditorActionListener */ public void onEditorAction(int actionCode) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) ((InternalEditText) mInputView).superOnEditorAction(actionCode); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) ((InternalAutoCompleteTextView) mInputView).superOnEditorAction(actionCode); else ((InternalMultiAutoCompleteTextView) mInputView).superOnEditorAction(actionCode); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return ((InternalEditText) mInputView).superOnKeyDown(keyCode, event); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) return ((InternalAutoCompleteTextView) mInputView).superOnKeyDown(keyCode, event); else return ((InternalMultiAutoCompleteTextView) mInputView).superOnKeyDown(keyCode, event); } @Override public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return ((InternalEditText) mInputView).superOnKeyMultiple(keyCode, repeatCount, event); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) return ((InternalAutoCompleteTextView) mInputView).superOnKeyMultiple(keyCode, repeatCount, event); else return ((InternalMultiAutoCompleteTextView) mInputView).superOnKeyMultiple(keyCode, repeatCount, event); } @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return ((InternalEditText) mInputView).superOnKeyPreIme(keyCode, event); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) return ((InternalAutoCompleteTextView) mInputView).superOnKeyPreIme(keyCode, event); else return ((InternalMultiAutoCompleteTextView) mInputView).superOnKeyPreIme(keyCode, event); } @Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return ((InternalEditText) mInputView).superOnKeyShortcut(keyCode, event); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) return ((InternalAutoCompleteTextView) mInputView).superOnKeyShortcut(keyCode, event); else return ((InternalMultiAutoCompleteTextView) mInputView).superOnKeyShortcut(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (mAutoCompleteMode == AUTOCOMPLETE_MODE_NONE) return ((InternalEditText) mInputView).superOnKeyUp(keyCode, event); else if (mAutoCompleteMode == AUTOCOMPLETE_MODE_SINGLE) return ((InternalAutoCompleteTextView) mInputView).superOnKeyUp(keyCode, event); else return ((InternalMultiAutoCompleteTextView) mInputView).superOnKeyUp(keyCode, event); } public void setOnSelectionChangedListener(TextView.OnSelectionChangedListener listener) { mOnSelectionChangedListener = listener; } /** * This method is called when the selection has changed, in case any * subclasses would like to know. * * @param selStart The new selection start location. * @param selEnd The new selection end location. */ protected void onSelectionChanged(int selStart, int selEnd) { if (mInputView == null) return; if (mInputView instanceof InternalEditText) ((InternalEditText) mInputView).superOnSelectionChanged(selStart, selEnd); else if (mInputView instanceof InternalAutoCompleteTextView) ((InternalAutoCompleteTextView) mInputView).superOnSelectionChanged(selStart, selEnd); else ((InternalMultiAutoCompleteTextView) mInputView).superOnSelectionChanged(selStart, selEnd); if (mOnSelectionChangedListener != null) mOnSelectionChangedListener.onSelectionChanged(this, selStart, selEnd); } /** * Removes the specified TextWatcher from the list of those whose * methods are called * whenever this TextView's text changes. */ public void removeTextChangedListener(TextWatcher watcher) { mInputView.removeTextChangedListener(watcher); } /** * Sets the properties of this field to transform input to ALL CAPS * display. This may use a "small caps" formatting if available. * This setting will be ignored if this field is editable or selectable. * * This call replaces the current transformation method. Disabling this * will not necessarily restore the previous behavior from before this * was enabled. * * @see #setTransformationMethod(TransformationMethod) * @attr ref android.R.styleable#TextView_textAllCaps */ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public void setAllCaps(boolean allCaps) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) mInputView.setAllCaps(allCaps); } /** * Sets the autolink mask of the text. See {@link * android.text.util.Linkify#ALL Linkify.ALL} and peers for * possible values. * * @attr ref android.R.styleable#TextView_autoLink */ public final void setAutoLinkMask(int mask) { mInputView.setAutoLinkMask(mask); } /** * Sets the size of the padding between the compound drawables and * the text. * * @attr ref android.R.styleable#TextView_drawablePadding */ public void setCompoundDrawablePadding(int pad) { mInputView.setCompoundDrawablePadding(pad); if (mDividerCompoundPadding) { mDivider.setPadding(mInputView.getTotalPaddingLeft(), mInputView.getTotalPaddingRight()); if (mLabelEnable) mLabelView.setPadding(mDivider.getPaddingLeft(), mLabelView.getPaddingTop(), mDivider.getPaddingRight(), mLabelView.getPaddingBottom()); if (mSupportMode != SUPPORT_MODE_NONE) mSupportView.setPadding(mDivider.getPaddingLeft(), mSupportView.getPaddingTop(), mDivider.getPaddingRight(), mSupportView.getPaddingBottom()); } } /** * Sets the Drawables (if any) to appear to the left of, above, to the * right of, and below the text. Use {@code null} if you do not want a * Drawable there. The Drawables must already have had * {@link Drawable#setBounds} called. * <p> * Calling this method will overwrite any Drawables previously set using * {@link #setCompoundDrawablesRelative} or related methods. * * @attr ref android.R.styleable#TextView_drawableLeft * @attr ref android.R.styleable#TextView_drawableTop * @attr ref android.R.styleable#TextView_drawableRight * @attr ref android.R.styleable#TextView_drawableBottom */ public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) { mInputView.setCompoundDrawables(left, top, right, bottom); if (mDividerCompoundPadding) { mDivider.setPadding(mInputView.getTotalPaddingLeft(), mInputView.getTotalPaddingRight()); if (mLabelEnable) mLabelView.setPadding(mDivider.getPaddingLeft(), mLabelView.getPaddingTop(), mDivider.getPaddingRight(), mLabelView.getPaddingBottom()); if (mSupportMode != SUPPORT_MODE_NONE) mSupportView.setPadding(mDivider.getPaddingLeft(), mSupportView.getPaddingTop(), mDivider.getPaddingRight(), mSupportView.getPaddingBottom()); } } /** * Sets the Drawables (if any) to appear to the start of, above, to the end * of, and below the text. Use {@code null} if you do not want a Drawable * there. The Drawables must already have had {@link Drawable#setBounds} * called. * <p> * Calling this method will overwrite any Drawables previously set using * {@link #setCompoundDrawables} or related methods. * * @attr ref android.R.styleable#TextView_drawableStart * @attr ref android.R.styleable#TextView_drawableTop * @attr ref android.R.styleable#TextView_drawableEnd * @attr ref android.R.styleable#TextView_drawableBottom */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public void setCompoundDrawablesRelative(Drawable start, Drawable top, Drawable end, Drawable bottom) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) mInputView.setCompoundDrawablesRelative(start, top, end, bottom); else mInputView.setCompoundDrawables(start, top, end, bottom); } /** * Sets the Drawables (if any) to appear to the start of, above, to the end * of, and below the text. Use {@code null} if you do not want a Drawable * there. The Drawables' bounds will be set to their intrinsic bounds. * <p> * Calling this method will overwrite any Drawables previously set using * {@link #setCompoundDrawables} or related methods. * * @attr ref android.R.styleable#TextView_drawableStart * @attr ref android.R.styleable#TextView_drawableTop * @attr ref android.R.styleable#TextView_drawableEnd * @attr ref android.R.styleable#TextView_drawableBottom */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public void setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable start, Drawable top, Drawable end, Drawable bottom) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) mInputView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom); else mInputView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom); } /** * Sets the Drawables (if any) to appear to the start of, above, to the end * of, and below the text. Use 0 if you do not want a Drawable there. The * Drawables' bounds will be set to their intrinsic bounds. * <p> * Calling this method will overwrite any Drawables previously set using * {@link #setCompoundDrawables} or related methods. * * @param start Resource identifier of the start Drawable. * @param top Resource identifier of the top Drawable. * @param end Resource identifier of the end Drawable. * @param bottom Resource identifier of the bottom Drawable. * * @attr ref android.R.styleable#TextView_drawableStart * @attr ref android.R.styleable#TextView_drawableTop * @attr ref android.R.styleable#TextView_drawableEnd * @attr ref android.R.styleable#TextView_drawableBottom */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public void setCompoundDrawablesRelativeWithIntrinsicBounds(int start, int top, int end, int bottom) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) mInputView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom); else mInputView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom); } /** * Sets the Drawables (if any) to appear to the left of, above, to the * right of, and below the text. Use {@code null} if you do not want a * Drawable there. The Drawables' bounds will be set to their intrinsic * bounds. * <p> * Calling this method will overwrite any Drawables previously set using * {@link #setCompoundDrawablesRelative} or related methods. * * @attr ref android.R.styleable#TextView_drawableLeft * @attr ref android.R.styleable#TextView_drawableTop * @attr ref android.R.styleable#TextView_drawableRight * @attr ref android.R.styleable#TextView_drawableBottom */ public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) { mInputView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom); } /** * Sets the Drawables (if any) to appear to the left of, above, to the * right of, and below the text. Use 0 if you do not want a Drawable there. * The Drawables' bounds will be set to their intrinsic bounds. * <p> * Calling this method will overwrite any Drawables previously set using * {@link #setCompoundDrawablesRelative} or related methods. * * @param left Resource identifier of the left Drawable. * @param top Resource identifier of the top Drawable. * @param right Resource identifier of the right Drawable. * @param bottom Resource identifier of the bottom Drawable. * * @attr ref android.R.styleable#TextView_drawableLeft * @attr ref android.R.styleable#TextView_drawableTop * @attr ref android.R.styleable#TextView_drawableRight * @attr ref android.R.styleable#TextView_drawableBottom */ public void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) { mInputView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom); } /** * Set whether the cursor is visible. The default is true. Note that this property only * makes sense for editable TextView. * * @see #isCursorVisible() * * @attr ref android.R.styleable#TextView_cursorVisible */ public void setCursorVisible(boolean visible) { mInputView.setCursorVisible(visible); } /** * If provided, this ActionMode.Callback will be used to create the ActionMode when text * selection is initiated in this View. * * The standard implementation populates the menu with a subset of Select All, Cut, Copy and * Paste actions, depending on what this View supports. * * A custom implementation can add new entries in the default menu in its * {@link ActionMode.Callback#onPrepareActionMode(ActionMode, android.view.Menu)} method. The * default actions can also be removed from the menu using {@link android.view.Menu#removeItem(int)} and * passing {@link android.R.id#selectAll}, {@link android.R.id#cut}, {@link android.R.id#copy} * or {@link android.R.id#paste} ids as parameters. * * Returning false from * {@link ActionMode.Callback#onCreateActionMode(ActionMode, android.view.Menu)} will prevent * the action mode from being started. * * Action click events should be handled by the custom implementation of * {@link ActionMode.Callback#onActionItemClicked(ActionMode, android.view.MenuItem)}. * * Note that text selection mode is not started when a TextView receives focus and the * {@link android.R.attr#selectAllOnFocus} flag has been set. The content is highlighted in * that case, to allow for quick replacement. */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) mInputView.setCustomSelectionActionModeCallback(actionModeCallback); } /** * Sets the Factory used to create new Editables. */ public final void setEditableFactory(Editable.Factory factory) { mInputView.setEditableFactory(factory); } /** * Set the TextView's elegant height metrics flag. This setting selects font * variants that have not been compacted to fit Latin-based vertical * metrics, and also increases top and bottom bounds to provide more space. * * @param elegant set the paint's elegant metrics flag. * * @attr ref android.R.styleable#TextView_elegantTextHeight */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void setElegantTextHeight(boolean elegant) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) mInputView.setElegantTextHeight(elegant); } /** * Makes the TextView exactly this many ems wide * * @see #setMaxEms(int) * @see #setMinEms(int) * @see #getMinEms() * @see #getMaxEms() * * @attr ref android.R.styleable#TextView_ems */ public void setEms(int ems) { mInputView.setEms(ems); } /** * Apply to this text view the given extracted text, as previously * returned by {@link #extractText(ExtractedTextRequest, ExtractedText)}. */ public void setExtractedText(ExtractedText text) { mInputView.setExtractedText(text); } /** * Sets the list of input filters that will be used if the buffer is * Editable. Has no effect otherwise. * * @attr ref android.R.styleable#TextView_maxLength */ public void setFilters(InputFilter[] filters) { mInputView.setFilters(filters); } /** * Sets font feature settings. The format is the same as the CSS * font-feature-settings attribute: * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings * * @param fontFeatureSettings font feature settings represented as CSS compatible string * @see #getFontFeatureSettings() * @see android.graphics.Paint#getFontFeatureSettings * * @attr ref android.R.styleable#TextView_fontFeatureSettings */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void setFontFeatureSettings(String fontFeatureSettings) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) mInputView.setFontFeatureSettings(fontFeatureSettings); } /** * Control whether this text view saves its entire text contents when * freezing to an icicle, in addition to dynamic state such as cursor * position. By default this is false, not saving the text. Set to true * if the text in the text view is not being saved somewhere else in * persistent storage (such as in a content provider) so that if the * view is later thawed the user will not lose their data. * * @param freezesText Controls whether a frozen icicle should include the * entire text data: true to include it, false to not. * * @attr ref android.R.styleable#TextView_freezesText */ public void setFreezesText(boolean freezesText) { mInputView.setFreezesText(freezesText); } /** * Sets the horizontal alignment of the text and the * vertical gravity that will be used when there is extra space * in the TextView beyond what is required for the text itself. * * @see Gravity * @attr ref android.R.styleable#TextView_gravity */ public void setGravity(int gravity) { mInputView.setGravity(gravity); } /** * Sets the color used to display the selection highlight. * * @attr ref android.R.styleable#TextView_textColorHighlight */ public void setHighlightColor(int color) { mInputView.setHighlightColor(color); } /** * Sets the text to be displayed when the text of the TextView is empty. * Null means to use the normal empty text. The hint does not currently * participate in determining the size of the view. * * @attr ref android.R.styleable#TextView_hint */ public final void setHint(CharSequence hint) { mInputView.setHint(hint); if (mLabelView != null) mLabelView.setText(hint); } /** * Sets the text to be displayed when the text of the TextView is empty, * from a resource. * * @attr ref android.R.styleable#TextView_hint */ public final void setHint(int resid) { mInputView.setHint(resid); if (mLabelView != null) mLabelView.setText(resid); } /** * Sets the color of the hint text. * * @see #getHintTextColors() * @see #setHintTextColor(int) * @see #setTextColor(ColorStateList) * @see #setLinkTextColor(ColorStateList) * * @attr ref android.R.styleable#TextView_textColorHint */ public final void setHintTextColor(ColorStateList colors) { mInputView.setHintTextColor(colors); } /** * Sets the color of the hint text for all the states (disabled, focussed, selected...) of this * TextView. * * @see #setHintTextColor(ColorStateList) * @see #getHintTextColors() * @see #setTextColor(int) * * @attr ref android.R.styleable#TextView_textColorHint */ public final void setHintTextColor(int color) { mInputView.setHintTextColor(color); } /** * Sets whether the text should be allowed to be wider than the * View is. If false, it will be wrapped to the width of the View. * * @attr ref android.R.styleable#TextView_scrollHorizontally */ public void setHorizontallyScrolling(boolean whether) { mInputView.setHorizontallyScrolling(whether); } /** * Change the custom IME action associated with the text view, which * will be reported to an IME with {@link EditorInfo#actionLabel} * and {@link EditorInfo#actionId} when it has focus. * @see #getImeActionLabel * @see #getImeActionId * @see EditorInfo * @attr ref android.R.styleable#TextView_imeActionLabel * @attr ref android.R.styleable#TextView_imeActionId */ public void setImeActionLabel(CharSequence label, int actionId) { mInputView.setImeActionLabel(label, actionId); } /** * Change the editor type integer associated with the text view, which * will be reported to an IME with {@link EditorInfo#imeOptions} when it * has focus. * @see #getImeOptions * @see EditorInfo * @attr ref android.R.styleable#TextView_imeOptions */ public void setImeOptions(int imeOptions) { mInputView.setImeOptions(imeOptions); } /** * Set whether the TextView includes extra top and bottom padding to make * room for accents that go above the normal ascent and descent. * The default is true. * * @see #getIncludeFontPadding() * * @attr ref android.R.styleable#TextView_includeFontPadding */ public void setIncludeFontPadding(boolean includepad) { mInputView.setIncludeFontPadding(includepad); } /** * Set the extra input data of the text, which is the * {@link EditorInfo#extras TextBoxAttribute.extras} * Bundle that will be filled in when creating an input connection. The * given integer is the resource ID of an XML resource holding an * {android.R.styleable#InputExtras <input-extras>} XML tree. * * @see #getInputExtras(boolean) * @see EditorInfo#extras * @attr ref android.R.styleable#TextView_editorExtras */ public void setInputExtras(int xmlResId) throws XmlPullParserException, IOException { mInputView.setInputExtras(xmlResId); } /** * Set the type of the content with a constant as defined for {@link EditorInfo#inputType}. This * will take care of changing the key listener, by calling {@link #setKeyListener(KeyListener)}, * to match the given content type. If the given content type is {@link EditorInfo#TYPE_NULL} * then a soft keyboard will not be displayed for this text view. * * Note that the maximum number of displayed lines (see {@link #setMaxLines(int)}) will be * modified if you change the {@link EditorInfo#TYPE_TEXT_FLAG_MULTI_LINE} flag of the input * type. * * @see #getInputType() * @see #setRawInputType(int) * @see android.text.InputType * @attr ref android.R.styleable#TextView_inputType */ public void setInputType(int type) { mInputView.setInputType(type); } /** * Sets the key listener to be used with this TextView. This can be null * to disallow user input. Note that this method has significant and * subtle interactions with soft keyboards and other input method: * see {@link KeyListener#getInputType() KeyListener.getContentType()} * for important details. Calling this method will replace the current * content type of the text view with the content type returned by the * key listener. * <p> * Be warned that if you want a TextView with a key listener or movement * method not to be focusable, or if you want a TextView without a * key listener or movement method to be focusable, you must call * {@link #setFocusable} again after calling this to get the focusability * back the way you want it. * * @attr ref android.R.styleable#TextView_numeric * @attr ref android.R.styleable#TextView_digits * @attr ref android.R.styleable#TextView_phoneNumber * @attr ref android.R.styleable#TextView_inputMethod * @attr ref android.R.styleable#TextView_capitalize * @attr ref android.R.styleable#TextView_autoText */ public void setKeyListener(KeyListener input) { mInputView.setKeyListener(input); } /** * Sets text letter-spacing. The value is in 'EM' units. Typical values * for slight expansion will be around 0.05. Negative values tighten text. * * @see #getLetterSpacing() * @see android.graphics.Paint#getLetterSpacing * * @attr ref android.R.styleable#TextView_letterSpacing */ public void setLetterSpacing(float letterSpacing) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) mInputView.setLetterSpacing(letterSpacing); } /** * Sets line spacing for this TextView. Each line will have its height * multiplied by <code>mult</code> and have <code>add</code> added to it. * * @attr ref android.R.styleable#TextView_lineSpacingExtra * @attr ref android.R.styleable#TextView_lineSpacingMultiplier */ public void setLineSpacing(float add, float mult) { mInputView.setLineSpacing(add, mult); } /** * Makes the TextView exactly this many lines tall. * * Note that setting this value overrides any other (minimum / maximum) number of lines or * height setting. A single line TextView will set this value to 1. * * @attr ref android.R.styleable#TextView_lines */ public void setLines(int lines) { mInputView.setLines(lines); } /** * Sets the color of links in the text. * * @see #setLinkTextColor(int) * @see #getLinkTextColors() * @see #setTextColor(ColorStateList) * @see #setHintTextColor(ColorStateList) * * @attr ref android.R.styleable#TextView_textColorLink */ public final void setLinkTextColor(ColorStateList colors) { mInputView.setLinkTextColor(colors); } /** * Sets the color of links in the text. * * @see #setLinkTextColor(int) * @see #getLinkTextColors() * @see #setTextColor(ColorStateList) * @see #setHintTextColor(ColorStateList) * * @attr ref android.R.styleable#TextView_textColorLink */ public final void setLinkTextColor(int color) { mInputView.setLinkTextColor(color); } /** * Sets whether the movement method will automatically be set to * {@link android.text.method.LinkMovementMethod} if {@link #setAutoLinkMask} has been * set to nonzero and links are detected in {@link #setText}. * The default is true. * * @attr ref android.R.styleable#TextView_linksClickable */ public final void setLinksClickable(boolean whether) { mInputView.setLinksClickable(whether); } /** * Sets how many times to repeat the marquee animation. Only applied if the * TextView has marquee enabled. Set to -1 to repeat indefinitely. * * @see #getMarqueeRepeatLimit() * * @attr ref android.R.styleable#TextView_marqueeRepeatLimit */ public void setMarqueeRepeatLimit(int marqueeLimit) { mInputView.setMarqueeRepeatLimit(marqueeLimit); } /** * Makes the TextView at most this many ems wide * * @attr ref android.R.styleable#TextView_maxEms */ public void setMaxEms(int maxems) { mInputView.setMaxEms(maxems); } /** * Makes the TextView at most this many pixels tall. This option is mutually exclusive with the * {@link #setMaxLines(int)} method. * * Setting this value overrides any other (maximum) number of lines setting. * * @attr ref android.R.styleable#TextView_maxHeight */ public void setMaxHeight(int maxHeight) { mInputView.setMaxHeight(maxHeight); } /** * Makes the TextView at most this many lines tall. * * Setting this value overrides any other (maximum) height setting. * * @attr ref android.R.styleable#TextView_maxLines */ public void setMaxLines(int maxlines) { mInputView.setMaxLines(maxlines); } /** * Makes the TextView at most this many pixels wide * * @attr ref android.R.styleable#TextView_maxWidth */ public void setMaxWidth(int maxpixels) { mInputView.setMaxWidth(maxpixels); } /** * Makes the TextView at least this many ems wide * * @attr ref android.R.styleable#TextView_minEms */ public void setMinEms(int minems) { mInputView.setMinEms(minems); } /** * Makes the TextView at least this many pixels tall. * * Setting this value overrides any other (minimum) number of lines setting. * * @attr ref android.R.styleable#TextView_minHeight */ public void setMinHeight(int minHeight) { mInputView.setMinHeight(minHeight); } /** * Makes the TextView at least this many lines tall. * * Setting this value overrides any other (minimum) height setting. A single line TextView will * set this value to 1. * * @see #getMinLines() * * @attr ref android.R.styleable#TextView_minLines */ public void setMinLines(int minlines) { mInputView.setMinLines(minlines); } /** * Makes the TextView at least this many pixels wide * * @attr ref android.R.styleable#TextView_minWidth */ public void setMinWidth(int minpixels) { mInputView.setMinWidth(minpixels); } /** * Sets the movement method (arrow key handler) to be used for * this TextView. This can be null to disallow using the arrow keys * to move the cursor or scroll the view. * <p> * Be warned that if you want a TextView with a key listener or movement * method not to be focusable, or if you want a TextView without a * key listener or movement method to be focusable, you must call * {@link #setFocusable} again after calling this to get the focusability * back the way you want it. */ public final void setMovementMethod(MovementMethod movement) { mInputView.setMovementMethod(movement); } /** * Set a special listener to be called when an action is performed * on the text view. This will be called when the enter key is pressed, * or when an action supplied to the IME is selected by the user. Setting * this means that the normal hard key event will not insert a newline * into the text view, even if it is multi-line; holding down the ALT * modifier will, however, allow the user to insert a newline character. */ public void setOnEditorActionListener(TextView.OnEditorActionListener l) { mInputView.setOnEditorActionListener(l); } /** * Register a callback to be invoked when a hardware key is pressed in this view. * Key presses in software input methods will generally not trigger the methods of * this listener. * @param l the key listener to attach to this view */ @Override public void setOnKeyListener(OnKeyListener l) { mInputView.setOnKeyListener(l); } /** * Register a callback to be invoked when focus of this view changed. * * @param l The callback that will run. */ @Override public void setOnFocusChangeListener(OnFocusChangeListener l) { mInputView.setOnFocusChangeListener(l); } /** * Directly change the content type integer of the text view, without * modifying any other state. * @see #setInputType(int) * @see android.text.InputType * @attr ref android.R.styleable#TextView_inputType */ public void setRawInputType(int type) { mInputView.setRawInputType(type); } public void setScroller(Scroller s) { mInputView.setScroller(s); } /** * Set the TextView so that when it takes focus, all the text is * selected. * * @attr ref android.R.styleable#TextView_selectAllOnFocus */ public void setSelectAllOnFocus(boolean selectAllOnFocus) { mInputView.setSelectAllOnFocus(selectAllOnFocus); } @Override public void setSelected(boolean selected) { mInputView.setSelected(selected); } /** * Gives the text a shadow of the specified blur radius and color, the specified * distance from its drawn position. * <p> * The text shadow produced does not interact with the properties on view * that are responsible for real time shadows, * {@link View#getElevation() elevation} and * {@link View#getTranslationZ() translationZ}. * * @see android.graphics.Paint#setShadowLayer(float, float, float, int) * * @attr ref android.R.styleable#TextView_shadowColor * @attr ref android.R.styleable#TextView_shadowDx * @attr ref android.R.styleable#TextView_shadowDy * @attr ref android.R.styleable#TextView_shadowRadius */ public void setShadowLayer(float radius, float dx, float dy, int color) { mInputView.setShadowLayer(radius, dx, dy, color); } /** * Sets whether the soft input method will be made visible when this * TextView gets focused. The default is true. */ public final void setShowSoftInputOnFocus(boolean show) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mInputView.setShowSoftInputOnFocus(show); } } /** * Sets the properties of this field (lines, horizontally scrolling, * transformation method) to be for a single-line input. * * @attr ref android.R.styleable#TextView_singleLine */ public void setSingleLine() { mInputView.setSingleLine(); } /** * Sets the Factory used to create new Spannables. */ public final void setSpannableFactory(Spannable.Factory factory) { mInputView.setSpannableFactory(factory); } public final void setText(int resid) { mInputView.setText(resid); } public final void setText(char[] text, int start, int len) { mInputView.setText(text, start, len); } public final void setText(int resid, TextView.BufferType type) { mInputView.setText(resid, type); } public final void setText(CharSequence text) { mInputView.setText(text); } /** * Sets the text color, size, style, hint color, and highlight color * from the specified TextAppearance resource. */ public void setTextAppearance(Context context, int resid) { mInputView.setTextAppearance(context, resid); } /** * Sets the text color. * * @see #setTextColor(int) * @see #getTextColors() * @see #setHintTextColor(ColorStateList) * @see #setLinkTextColor(ColorStateList) * * @attr ref android.R.styleable#TextView_textColor */ public void setTextColor(ColorStateList colors) { mInputView.setTextColor(colors); } /** * Sets the text color for all the states (normal, selected, * focused) to be this color. * * @see #setTextColor(ColorStateList) * @see #getTextColors() * * @attr ref android.R.styleable#TextView_textColor */ public void setTextColor(int color) { mInputView.setTextColor(color); } /** * Sets whether the content of this view is selectable by the user. The default is * {@code false}, meaning that the content is not selectable. * <p> * When you use a TextView to display a useful piece of information to the user (such as a * contact's address), make it selectable, so that the user can select and copy its * content. You can also use set the XML attribute * {android.R.styleable#TextView_textIsSelectable} to "true". * <p> * When you call this method to set the value of {@code textIsSelectable}, it sets * the flags {@code focusable}, {@code focusableInTouchMode}, {@code clickable}, * and {@code longClickable} to the same value. These flags correspond to the attributes * {android.R.styleable#View_focusable android:focusable}, * {android.R.styleable#View_focusableInTouchMode android:focusableInTouchMode}, * {android.R.styleable#View_clickable android:clickable}, and * {android.R.styleable#View_longClickable android:longClickable}. To restore any of these * flags to a state you had set previously, call one or more of the following methods: * {@link #setFocusable(boolean) setFocusable()}, * {@link #setFocusableInTouchMode(boolean) setFocusableInTouchMode()}, * {@link #setClickable(boolean) setClickable()} or * {@link #setLongClickable(boolean) setLongClickable()}. * * @param selectable Whether the content of this TextView should be selectable. */ @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void setTextIsSelectable(boolean selectable) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) mInputView.setTextIsSelectable(selectable); } /** * Like {@link #setText(CharSequence)}, * except that the cursor position (if any) is retained in the new text. * * @param text The new text to place in the text view. * * @see #setText(CharSequence) */ public final void setTextKeepState(CharSequence text) { mInputView.setTextKeepState(text); } /** * Like {@link #setText(CharSequence, TextView.BufferType)}, * except that the cursor position (if any) is retained in the new text. * * @see #setText(CharSequence, TextView.BufferType) */ public final void setTextKeepState(CharSequence text, TextView.BufferType type) { mInputView.setTextKeepState(text, type); } /** * Set the default {@link Locale} of the text in this TextView to the given value. This value * is used to choose appropriate typefaces for ambiguous characters. Typically used for CJK * locales to disambiguate Hanzi/Kanji/Hanja characters. * * @param locale the {@link Locale} for drawing text, must not be null. * * @see android.graphics.Paint#setTextLocale */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public void setTextLocale(Locale locale) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) mInputView.setTextLocale(locale); } /** * Sets the extent by which text should be stretched horizontally. * * @attr ref android.R.styleable#TextView_textScaleX */ public void setTextScaleX(float size) { mInputView.setTextScaleX(size); } /** * Set the default text size to the given value, interpreted as "scaled * pixel" units. This size is adjusted based on the current density and * user font size preference. * * @param size The scaled pixel size. * * @attr ref android.R.styleable#TextView_textSize */ public void setTextSize(float size) { mInputView.setTextSize(size); } /** * Set the default text size to a given unit and value. See {@link * TypedValue} for the possible dimension units. * * @param unit The desired dimension unit. * @param size The desired size in the given units. * * @attr ref android.R.styleable#TextView_textSize */ public void setTextSize(int unit, float size) { mInputView.setTextSize(unit, size); } /** * Sets the transformation that is applied to the text that this * TextView is displaying. * * @attr ref android.R.styleable#TextView_password * @attr ref android.R.styleable#TextView_singleLine */ public final void setTransformationMethod(TransformationMethod method) { mInputView.setTransformationMethod(method); } /** * Sets the typeface and style in which the text should be displayed, * and turns on the fake bold and italic bits in the Paint if the * Typeface that you provided does not have all the bits in the * style that you specified. * * @attr ref android.R.styleable#TextView_typeface * @attr ref android.R.styleable#TextView_textStyle */ public void setTypeface(Typeface tf, int style) { mInputView.setTypeface(tf, style); } /** * Sets the typeface and style in which the text should be displayed. * Note that not all Typeface families actually have bold and italic * variants, so you may need to use * {@link #setTypeface(Typeface, int)} to get the appearance * that you actually want. * * @see #getTypeface() * * @attr ref android.R.styleable#TextView_fontFamily * @attr ref android.R.styleable#TextView_typeface * @attr ref android.R.styleable#TextView_textStyle */ public void setTypeface(Typeface tf) { mInputView.setTypeface(tf); } /** * It would be better to rely on the input type for everything. A password inputType should have * a password transformation. We should hence use isPasswordInputType instead of this method. * * We should: * - Call setInputType in setKeyListener instead of changing the input type directly (which * would install the correct transformation). * - Refuse the installation of a non-password transformation in setTransformation if the input * type is password. * * However, this is like this for legacy reasons and we cannot break existing apps. This method * is useful since it matches what the user can see (obfuscated text or not). * * @return true if the current transformation method is of the password type. */ private boolean hasPasswordTransformationMethod() { return getTransformationMethod() != null && getTransformationMethod() instanceof PasswordTransformationMethod; } public boolean canCut() { return !hasPasswordTransformationMethod() && getText().length() > 0 && hasSelection() && getKeyListener() != null; } public boolean canCopy() { return !hasPasswordTransformationMethod() && getText().length() > 0 && hasSelection(); } public boolean canPaste() { return (getKeyListener() != null && getSelectionStart() >= 0 && getSelectionEnd() >= 0 && ((ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE)).hasPrimaryClip()); } /* Inner class */ private class InputTextWatcher implements TextWatcher { @Override public void afterTextChanged(Editable s) { int count = s.length(); setLabelVisible(count != 0, true); if (mSupportMode == SUPPORT_MODE_CHAR_COUNTER) updateCharCounter(count); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } } private class LabelView extends TextView { public LabelView(Context context) { super(context); } @Override public void setTextAppearance(int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override public void setTextAppearance(Context context, int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override protected int[] onCreateDrawableState(int extraSpace) { return mInputView.getDrawableState(); } } private class InternalEditText extends AppCompatEditText { public InternalEditText(Context context) { super(context); } public InternalEditText(Context context, AttributeSet attrs) { super(context, attrs); } public InternalEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setTextAppearance(int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override public void setTextAppearance(Context context, int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override public void refreshDrawableState() { super.refreshDrawableState(); if (mLabelView != null) mLabelView.refreshDrawableState(); if (mSupportView != null) mSupportView.refreshDrawableState(); } @Override public void onCommitCompletion(CompletionInfo text) { EditText.this.onCommitCompletion(text); } @Override public void onCommitCorrection(CorrectionInfo info) { EditText.this.onCommitCorrection(info); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return EditText.this.onCreateInputConnection(outAttrs); } @Override public void onEditorAction(int actionCode) { EditText.this.onEditorAction(actionCode); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return EditText.this.onKeyDown(keyCode, event); } @Override public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return EditText.this.onKeyMultiple(keyCode, repeatCount, event); } @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { return EditText.this.onKeyPreIme(keyCode, event); } @Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { return EditText.this.onKeyShortcut(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return EditText.this.onKeyUp(keyCode, event); } @Override protected void onSelectionChanged(int selStart, int selEnd) { EditText.this.onSelectionChanged(selStart, selEnd); } void superOnCommitCompletion(CompletionInfo text) { super.onCommitCompletion(text); } void superOnCommitCorrection(CorrectionInfo info) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) super.onCommitCorrection(info); } InputConnection superOnCreateInputConnection(EditorInfo outAttrs) { return super.onCreateInputConnection(outAttrs); } void superOnEditorAction(int actionCode) { super.onEditorAction(actionCode); } boolean superOnKeyDown(int keyCode, KeyEvent event) { return super.onKeyDown(keyCode, event); } boolean superOnKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return super.onKeyMultiple(keyCode, repeatCount, event); } boolean superOnKeyPreIme(int keyCode, KeyEvent event) { return super.onKeyPreIme(keyCode, event); } boolean superOnKeyShortcut(int keyCode, KeyEvent event) { return super.onKeyShortcut(keyCode, event); } boolean superOnKeyUp(int keyCode, KeyEvent event) { return super.onKeyUp(keyCode, event); } void superOnSelectionChanged(int selStart, int selEnd) { super.onSelectionChanged(selStart, selEnd); } } private class InternalAutoCompleteTextView extends AppCompatAutoCompleteTextView { public InternalAutoCompleteTextView(Context context) { super(context); } public InternalAutoCompleteTextView(Context context, AttributeSet attrs) { super(context, attrs); } public InternalAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setTextAppearance(int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override public void setTextAppearance(Context context, int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override public void refreshDrawableState() { super.refreshDrawableState(); if (mLabelView != null) mLabelView.refreshDrawableState(); if (mSupportView != null) mSupportView.refreshDrawableState(); } @Override public void onCommitCompletion(CompletionInfo text) { EditText.this.onCommitCompletion(text); } @Override public void onCommitCorrection(CorrectionInfo info) { EditText.this.onCommitCorrection(info); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return EditText.this.onCreateInputConnection(outAttrs); } @Override public void onEditorAction(int actionCode) { EditText.this.onEditorAction(actionCode); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return EditText.this.onKeyDown(keyCode, event); } @Override public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return EditText.this.onKeyMultiple(keyCode, repeatCount, event); } @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { return EditText.this.onKeyPreIme(keyCode, event); } @Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { return EditText.this.onKeyShortcut(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return EditText.this.onKeyUp(keyCode, event); } @Override protected void onSelectionChanged(int selStart, int selEnd) { EditText.this.onSelectionChanged(selStart, selEnd); } @Override protected CharSequence convertSelectionToString(Object selectedItem) { return EditText.this.convertSelectionToString(selectedItem); } @Override protected void performFiltering(CharSequence text, int keyCode) { EditText.this.performFiltering(text, keyCode); } @Override protected void replaceText(CharSequence text) { EditText.this.replaceText(text); } @Override protected Filter getFilter() { return EditText.this.getFilter(); } @Override public void onFilterComplete(int count) { EditText.this.onFilterComplete(count); } void superOnCommitCompletion(CompletionInfo text) { super.onCommitCompletion(text); } void superOnCommitCorrection(CorrectionInfo info) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) super.onCommitCorrection(info); } InputConnection superOnCreateInputConnection(EditorInfo outAttrs) { return super.onCreateInputConnection(outAttrs); } void superOnEditorAction(int actionCode) { super.onEditorAction(actionCode); } boolean superOnKeyDown(int keyCode, KeyEvent event) { return super.onKeyDown(keyCode, event); } boolean superOnKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return super.onKeyMultiple(keyCode, repeatCount, event); } boolean superOnKeyPreIme(int keyCode, KeyEvent event) { return super.onKeyPreIme(keyCode, event); } boolean superOnKeyShortcut(int keyCode, KeyEvent event) { return super.onKeyShortcut(keyCode, event); } boolean superOnKeyUp(int keyCode, KeyEvent event) { return super.onKeyUp(keyCode, event); } void superOnFilterComplete(int count) { super.onFilterComplete(count); } CharSequence superConvertSelectionToString(Object selectedItem) { return super.convertSelectionToString(selectedItem); } void superPerformFiltering(CharSequence text, int keyCode) { super.performFiltering(text, keyCode); } void superReplaceText(CharSequence text) { super.replaceText(text); } Filter superGetFilter() { return super.getFilter(); } void superOnSelectionChanged(int selStart, int selEnd) { super.onSelectionChanged(selStart, selEnd); } } private class InternalMultiAutoCompleteTextView extends AppCompatMultiAutoCompleteTextView { public InternalMultiAutoCompleteTextView(Context context) { super(context); } public InternalMultiAutoCompleteTextView(Context context, AttributeSet attrs) { super(context, attrs); } public InternalMultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setTextAppearance(int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override public void setTextAppearance(Context context, int resId) { ViewUtil.applyTextAppearance(this, resId); } @Override public void refreshDrawableState() { super.refreshDrawableState(); if (mLabelView != null) mLabelView.refreshDrawableState(); if (mSupportView != null) mSupportView.refreshDrawableState(); } @Override public void onCommitCompletion(CompletionInfo text) { EditText.this.onCommitCompletion(text); } @Override public void onCommitCorrection(CorrectionInfo info) { EditText.this.onCommitCorrection(info); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { return EditText.this.onCreateInputConnection(outAttrs); } @Override public void onEditorAction(int actionCode) { EditText.this.onEditorAction(actionCode); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return EditText.this.onKeyDown(keyCode, event); } @Override public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return EditText.this.onKeyMultiple(keyCode, repeatCount, event); } @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { return EditText.this.onKeyPreIme(keyCode, event); } @Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { return EditText.this.onKeyShortcut(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return EditText.this.onKeyUp(keyCode, event); } @Override protected void onSelectionChanged(int selStart, int selEnd) { EditText.this.onSelectionChanged(selStart, selEnd); } @Override public void onFilterComplete(int count) { EditText.this.onFilterComplete(count); } @Override protected CharSequence convertSelectionToString(Object selectedItem) { return EditText.this.convertSelectionToString(selectedItem); } @Override protected void performFiltering(CharSequence text, int keyCode) { EditText.this.performFiltering(text, keyCode); } @Override protected void replaceText(CharSequence text) { EditText.this.replaceText(text); } @Override protected Filter getFilter() { return EditText.this.getFilter(); } @Override protected void performFiltering(CharSequence text, int start, int end, int keyCode) { EditText.this.performFiltering(text, start, end, keyCode); } void superOnCommitCompletion(CompletionInfo text) { super.onCommitCompletion(text); } void superOnCommitCorrection(CorrectionInfo info) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) super.onCommitCorrection(info); } InputConnection superOnCreateInputConnection(EditorInfo outAttrs) { return super.onCreateInputConnection(outAttrs); } void superOnEditorAction(int actionCode) { super.onEditorAction(actionCode); } boolean superOnKeyDown(int keyCode, KeyEvent event) { return super.onKeyDown(keyCode, event); } boolean superOnKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { return super.onKeyMultiple(keyCode, repeatCount, event); } boolean superOnKeyPreIme(int keyCode, KeyEvent event) { return super.onKeyPreIme(keyCode, event); } boolean superOnKeyShortcut(int keyCode, KeyEvent event) { return super.onKeyShortcut(keyCode, event); } boolean superOnKeyUp(int keyCode, KeyEvent event) { return super.onKeyUp(keyCode, event); } void superOnFilterComplete(int count) { super.onFilterComplete(count); } CharSequence superConvertSelectionToString(Object selectedItem) { return super.convertSelectionToString(selectedItem); } void superPerformFiltering(CharSequence text, int keyCode) { super.performFiltering(text, keyCode); } void superReplaceText(CharSequence text) { super.replaceText(text); } Filter superGetFilter() { return super.getFilter(); } void superPerformFiltering(CharSequence text, int start, int end, int keyCode) { super.performFiltering(text, start, end, keyCode); } void superOnSelectionChanged(int selStart, int selEnd) { super.onSelectionChanged(selStart, selEnd); } } }