Last active
August 29, 2015 14:25
-
-
Save yishai-glide/ea0b1dbd8c085cf80255 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* */ 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