Skip to content

Instantly share code, notes, and snippets.

@yishai-glide
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yishai-glide/ea0b1dbd8c085cf80255 to your computer and use it in GitHub Desktop.
Save yishai-glide/ea0b1dbd8c085cf80255 to your computer and use it in GitHub Desktop.
/* */ package android.support.design.widget;
/* */
/* */ import android.content.Context;
/* */ import android.content.res.ColorStateList;
/* */ import android.content.res.Resources.Theme;
/* */ import android.content.res.TypedArray;
/* */ import android.graphics.Canvas;
/* */ import android.graphics.Paint;
/* */ import android.os.Handler;
/* */ import android.os.Handler.Callback;
/* */ import android.os.Message;
/* */ import android.support.design.R.style;
/* */ import android.support.design.R.styleable;
/* */ import android.support.v4.view.AccessibilityDelegateCompat;
/* */ import android.support.v4.view.ViewCompat;
/* */ import android.support.v4.view.ViewPropertyAnimatorCompat;
/* */ import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
/* */ import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
/* */ import android.text.Editable;
/* */ import android.text.TextUtils;
/* */ import android.text.TextWatcher;
/* */ import android.util.AttributeSet;
/* */ import android.util.TypedValue;
/* */ import android.view.View;
/* */ import android.view.View.OnFocusChangeListener;
/* */ import android.view.ViewGroup.LayoutParams;
/* */ import android.view.accessibility.AccessibilityEvent;
/* */ import android.view.animation.AccelerateInterpolator;
/* */ import android.widget.EditText;
/* */ import android.widget.LinearLayout;
/* */ import android.widget.LinearLayout.LayoutParams;
/* */ import android.widget.TextView;
/* */ import java.util.List;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public class TextInputLayout
/* */ extends LinearLayout
/* */ {
/* */ private static final int ANIMATION_DURATION = 200;
/* */ private static final int MSG_UPDATE_LABEL = 0;
/* */ private EditText mEditText;
/* */ private CharSequence mHint;
/* */ private boolean mErrorEnabled;
/* */ private TextView mErrorView;
/* */ private int mErrorTextAppearance;
/* */ private ColorStateList mLabelTextColor;
/* */ private final CollapsingTextHelper mCollapsingTextHelper;
/* */ private final Handler mHandler;
/* */ private ValueAnimatorCompat mAnimator;
/* */
/* */ public TextInputLayout(Context context)
/* */ {
/* 73 */ this(context, null);
/* */ }
/* */
/* */ public TextInputLayout(Context context, AttributeSet attrs) {
/* 77 */ super(context, attrs);
/* */
/* 79 */ setOrientation(1);
/* 80 */ setWillNotDraw(false);
/* */
/* 82 */ this.mCollapsingTextHelper = new CollapsingTextHelper(this);
/* 83 */ this.mHandler = new Handler(new Handler.Callback()
/* */ {
/* */ public boolean handleMessage(Message message) {
/* 86 */ switch (message.what) {
/* */ case 0:
/* 88 */ TextInputLayout.this.updateLabelVisibility(true);
/* 89 */ return true;
/* */ }
/* 91 */ return false;
/* */ }
/* */
/* 94 */ });
/* 95 */ this.mCollapsingTextHelper.setTextSizeInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR);
/* 96 */ this.mCollapsingTextHelper.setPositionInterpolator(new AccelerateInterpolator());
/* 97 */ this.mCollapsingTextHelper.setCollapsedTextVerticalGravity(48);
/* */
/* 99 */ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextInputLayout, 0, R.style.Widget_Design_TextInputLayout);
/* */
/* 101 */ this.mHint = a.getText(R.styleable.TextInputLayout_android_hint);
/* */
/* 103 */ int hintAppearance = a.getResourceId(R.styleable.TextInputLayout_hintTextAppearance, -1);
/* */
/* 105 */ if (hintAppearance != -1) {
/* 106 */ this.mCollapsingTextHelper.setCollapsedTextAppearance(hintAppearance);
/* */ }
/* */
/* 109 */ this.mErrorTextAppearance = a.getResourceId(R.styleable.TextInputLayout_errorTextAppearance, 0);
/* 110 */ boolean errorEnabled = a.getBoolean(R.styleable.TextInputLayout_errorEnabled, false);
/* */
/* */
/* */
/* 114 */ this.mLabelTextColor = createLabelTextColorStateList(this.mCollapsingTextHelper.getCollapsedTextColor());
/* */
/* */
/* 117 */ this.mCollapsingTextHelper.setCollapsedTextColor(this.mLabelTextColor.getDefaultColor());
/* 118 */ this.mCollapsingTextHelper.setExpandedTextColor(this.mLabelTextColor.getDefaultColor());
/* */
/* 120 */ a.recycle();
/* */
/* 122 */ if (errorEnabled) {
/* 123 */ setErrorEnabled(true);
/* */ }
/* */
/* 126 */ if (ViewCompat.getImportantForAccessibility(this) == 0)
/* */ {
/* */
/* 129 */ ViewCompat.setImportantForAccessibility(this, 1);
/* */ }
/* */
/* */
/* 133 */ ViewCompat.setAccessibilityDelegate(this, new TextInputAccessibilityDelegate(null));
/* */ }
/* */
/* */ public void addView(View child, int index, ViewGroup.LayoutParams params)
/* */ {
/* 138 */ if ((child instanceof EditText)) {
/* 139 */ params = setEditText((EditText)child, params);
/* 140 */ super.addView(child, 0, params);
/* */ }
/* */ else {
/* 143 */ super.addView(child, index, params);
/* */ }
/* */ }
/* */
/* */ private LinearLayout.LayoutParams setEditText(EditText editText, ViewGroup.LayoutParams lp)
/* */ {
/* 149 */ if (this.mEditText != null) {
/* 150 */ throw new IllegalArgumentException("We already have an EditText, can only have one");
/* */ }
/* 152 */ this.mEditText = editText;
/* */
/* */
/* 155 */ this.mCollapsingTextHelper.setExpandedTextSize(this.mEditText.getTextSize());
/* */
/* */
/* 158 */ this.mEditText.addTextChangedListener(new TextWatcher()
/* */ {
/* */ public void afterTextChanged(Editable s) {
/* 161 */ TextInputLayout.this.mHandler.sendEmptyMessage(0);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
/* */
/* */
/* */
/* */
/* */ public void onTextChanged(CharSequence s, int start, int before, int count) {}
/* 174 */ });
/* 175 */ this.mEditText.setOnFocusChangeListener(new View.OnFocusChangeListener()
/* */ {
/* */ public void onFocusChange(View view, boolean focused) {
/* 178 */ TextInputLayout.this.mHandler.sendEmptyMessage(0);
/* */ }
/* */ });
/* */
/* */
/* 183 */ if (TextUtils.isEmpty(this.mHint)) {
/* 184 */ setHint(this.mEditText.getHint());
/* */
/* 186 */ this.mEditText.setHint(null);
/* */ }
/* */
/* 189 */ if (this.mErrorView != null)
/* */ {
/* 191 */ ViewCompat.setPaddingRelative(this.mErrorView, ViewCompat.getPaddingStart(this.mEditText), 0, ViewCompat.getPaddingEnd(this.mEditText), this.mEditText.getPaddingBottom());
/* */ }
/* */
/* */
/* */
/* 196 */ updateLabelVisibility(false);
/* */
/* */
/* */
/* 200 */ LinearLayout.LayoutParams newLp = new LinearLayout.LayoutParams(lp);
/* 201 */ Paint paint = new Paint();
/* 202 */ paint.setTextSize(this.mCollapsingTextHelper.getExpandedTextSize());
/* 203 */ newLp.topMargin = ((int)-paint.ascent());
/* */
/* 205 */ return newLp;
/* */ }
/* */
/* */ private void updateLabelVisibility(boolean animate) {
/* 209 */ boolean hasText = !TextUtils.isEmpty(this.mEditText.getText());
/* 210 */ boolean isFocused = this.mEditText.isFocused();
/* */
/* 212 */ this.mCollapsingTextHelper.setCollapsedTextColor(this.mLabelTextColor.getColorForState(isFocused ? FOCUSED_STATE_SET : EMPTY_STATE_SET, this.mLabelTextColor.getDefaultColor()));
/* */
/* */
/* */
/* 216 */ if ((hasText) || (isFocused))
/* */ {
/* 218 */ collapseHint(animate);
/* */ }
/* */ else {
/* 221 */ expandHint(animate);
/* */ }
/* */ }
/* */
/* */
/* */
/* */ public EditText getEditText()
/* */ {
/* 229 */ return this.mEditText;
/* */ }
/* */
/* */
/* */
/* */ public void setHint(CharSequence hint)
/* */ {
/* 236 */ this.mHint = hint;
/* 237 */ this.mCollapsingTextHelper.setText(hint);
/* */
/* 239 */ sendAccessibilityEvent(2048);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */ public void setErrorEnabled(boolean enabled)
/* */ {
/* 248 */ if (this.mErrorEnabled != enabled) {
/* 249 */ if (enabled) {
/* 250 */ this.mErrorView = new TextView(getContext());
/* 251 */ this.mErrorView.setTextAppearance(getContext(), this.mErrorTextAppearance);
/* 252 */ this.mErrorView.setVisibility(4);
/* 253 */ addView(this.mErrorView);
/* */
/* 255 */ if (this.mEditText != null)
/* */ {
/* 257 */ ViewCompat.setPaddingRelative(this.mErrorView, ViewCompat.getPaddingStart(this.mEditText), 0, ViewCompat.getPaddingEnd(this.mEditText), this.mEditText.getPaddingBottom());
/* */ }
/* */ }
/* */ else {
/* 261 */ removeView(this.mErrorView);
/* 262 */ this.mErrorView = null;
/* */ }
/* 264 */ this.mErrorEnabled = enabled;
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public void setError(CharSequence error)
/* */ {
/* 278 */ if (!this.mErrorEnabled) {
/* 279 */ if (TextUtils.isEmpty(error))
/* */ {
/* 281 */ return;
/* */ }
/* */
/* 284 */ setErrorEnabled(true);
/* */ }
/* */
/* 287 */ if (!TextUtils.isEmpty(error)) {
/* 288 */ this.mErrorView.setText(error);
/* 289 */ this.mErrorView.setVisibility(0);
/* 290 */ ViewCompat.setAlpha(this.mErrorView, 0.0F);
/* 291 */ ViewCompat.animate(this.mErrorView).alpha(1.0F).setDuration(200L).setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR).setListener(null).start();
/* */
/* */
/* */
/* */
/* */
/* */ }
/* 298 */ else if (this.mErrorView.getVisibility() == 0) {
/* 299 */ ViewCompat.animate(this.mErrorView).alpha(0.0F).setDuration(200L).setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR).setListener(new ViewPropertyAnimatorListenerAdapter()
/* */ {
/* */
/* */
/* */ public void onAnimationEnd(View view)
/* */ {
/* */
/* 306 */ TextInputLayout.this.mErrorView.setText(null);
/* 307 */ TextInputLayout.this.mErrorView.setVisibility(4);
/* */ }
/* */ }).start();
/* */ }
/* */
/* */
/* 313 */ sendAccessibilityEvent(2048);
/* */ }
/* */
/* */ public void draw(Canvas canvas)
/* */ {
/* 318 */ super.draw(canvas);
/* 319 */ this.mCollapsingTextHelper.draw(canvas);
/* */ }
/* */
/* */ protected void onLayout(boolean changed, int left, int top, int right, int bottom)
/* */ {
/* 324 */ super.onLayout(changed, left, top, right, bottom);
/* */
/* 326 */ this.mCollapsingTextHelper.onLayout(changed, left, top, right, bottom);
/* */
/* 328 */ if (this.mEditText != null) {
/* 329 */ int l = this.mEditText.getLeft() + this.mEditText.getPaddingLeft();
/* 330 */ int r = this.mEditText.getRight() - this.mEditText.getPaddingRight();
/* */
/* 332 */ this.mCollapsingTextHelper.setExpandedBounds(l, this.mEditText.getTop() + this.mEditText.getPaddingTop(), r, this.mEditText.getBottom() - this.mEditText.getPaddingBottom());
/* */
/* */
/* */
/* */
/* */
/* 338 */ this.mCollapsingTextHelper.setCollapsedBounds(l, getPaddingTop(), r, bottom - top - getPaddingBottom());
/* */ }
/* */ }
/* */
/* */ private void collapseHint(boolean animate)
/* */ {
/* 344 */ if (animate) {
/* 345 */ animateToExpansionFraction(1.0F);
/* */ } else {
/* 347 */ this.mCollapsingTextHelper.setExpansionFraction(1.0F);
/* */ }
/* */ }
/* */
/* */ private void expandHint(boolean animate) {
/* 352 */ if (animate) {
/* 353 */ animateToExpansionFraction(0.0F);
/* */ } else {
/* 355 */ this.mCollapsingTextHelper.setExpansionFraction(0.0F);
/* */ }
/* */ }
/* */
/* */ private void animateToExpansionFraction(float target) {
/* 360 */ if (this.mAnimator == null) {
/* 361 */ this.mAnimator = ViewUtils.createAnimator();
/* 362 */ this.mAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR);
/* 363 */ this.mAnimator.setDuration(200);
/* 364 */ this.mAnimator.setUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener()
/* */ {
/* */ public void onAnimationUpdate(ValueAnimatorCompat animator) {
/* 367 */ TextInputLayout.this.mCollapsingTextHelper.setExpansionFraction(animator.getAnimatedFloatValue());
/* */ }
/* */ });
/* 370 */ } else if (this.mAnimator.isRunning()) {
/* 371 */ this.mAnimator.cancel();
/* */ }
/* */
/* 374 */ this.mAnimator.setFloatValues(this.mCollapsingTextHelper.getExpansionFraction(), target);
/* 375 */ this.mAnimator.start();
/* */ }
/* */
/* */ private ColorStateList createLabelTextColorStateList(int color) {
/* 379 */ int[][] states = new int[2][];
/* 380 */ int[] colors = new int[2];
/* 381 */ int i = 0;
/* */
/* */
/* 384 */ states[i] = FOCUSED_STATE_SET;
/* 385 */ colors[i] = color;
/* 386 */ i++;
/* */
/* 388 */ states[i] = EMPTY_STATE_SET;
/* 389 */ colors[i] = getThemeAttrColor(16842906);
/* 390 */ i++;
/* */
/* 392 */ return new ColorStateList(states, colors);
/* */ }
/* */
/* */ private int getThemeAttrColor(int attr) {
/* 396 */ TypedValue tv = new TypedValue();
/* 397 */ if (getContext().getTheme().resolveAttribute(attr, tv, true)) {
/* 398 */ return tv.data;
/* */ }
/* 400 */ return -65281;
/* */ }
/* */
/* */ private class TextInputAccessibilityDelegate extends AccessibilityDelegateCompat {
/* */ private TextInputAccessibilityDelegate() {}
/* */
/* */ public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
/* 407 */ super.onInitializeAccessibilityEvent(host, event);
/* 408 */ event.setClassName(TextInputLayout.class.getSimpleName());
/* */ }
/* */
/* */ public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event)
/* */ {
/* 413 */ super.onPopulateAccessibilityEvent(host, event);
/* */
/* 415 */ CharSequence text = TextInputLayout.this.mCollapsingTextHelper.getText();
/* 416 */ if (!TextUtils.isEmpty(text)) {
/* 417 */ event.getText().add(text);
/* */ }
/* */ }
/* */
/* */ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info)
/* */ {
/* 423 */ super.onInitializeAccessibilityNodeInfo(host, info);
/* 424 */ info.setClassName(TextInputLayout.class.getSimpleName());
/* */
/* 426 */ CharSequence text = TextInputLayout.this.mCollapsingTextHelper.getText();
/* 427 */ if (!TextUtils.isEmpty(text)) {
/* 428 */ info.setText(text);
/* */ }
/* 430 */ if (TextInputLayout.this.mEditText != null) {
/* 431 */ info.setLabelFor(TextInputLayout.this.mEditText);
/* */ }
/* 433 */ CharSequence error = TextInputLayout.this.mErrorView != null ? TextInputLayout.this.mErrorView.getText() : null;
/* 434 */ if (!TextUtils.isEmpty(error)) {
/* 435 */ info.setContentInvalid(true);
/* 436 */ info.setError(error);
/* */ }
/* */ }
/* */ }
/* */ }
/* Location: /Applications/Android/sdk/extras/android/support/design/libs/android-support-design.jar
* Qualified Name: android.support.design.widget.TextInputLayout
* Java Class Version: 7 (51.0)
* JD-Core Version: 0.7.0.1
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment