package skin.support.design.widget; import android.content.Context; import android.content.res.ColorStateList; import android.support.annotation.StyleRes; import android.support.design.widget.TextInputLayout; import android.support.v7.widget.TintTypedArray; import android.util.AttributeSet; import android.widget.TextView; import java.lang.reflect.Field; import java.lang.reflect.Method; import skin.support.content.res.SkinCompatResources; import skin.support.design.R; import skin.support.utils.SkinLog; import skin.support.widget.SkinCompatBackgroundHelper; import skin.support.widget.SkinCompatEditText; import skin.support.widget.SkinCompatHelper; import skin.support.widget.SkinCompatSupportable; import static skin.support.widget.SkinCompatHelper.INVALID_ID; /** * Created by ximsfei on 17-3-2. */ public class SkinMaterialTextInputLayout extends TextInputLayout implements SkinCompatSupportable { private static final String TAG = SkinMaterialTextInputLayout.class.getSimpleName(); private SkinCompatBackgroundHelper mBackgroundTintHelper; private int mPasswordToggleResId = INVALID_ID; private int mCounterTextColorResId = INVALID_ID; private int mErrorTextColorResId = INVALID_ID; private int mFocusedTextColorResId = INVALID_ID; private int mDefaultTextColorResId = INVALID_ID; private boolean mSkinSupport = true; public SkinMaterialTextInputLayout(Context context) { this(context, null); } public SkinMaterialTextInputLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SkinMaterialTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mBackgroundTintHelper = new SkinCompatBackgroundHelper(this); mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr); final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.TextInputLayout, defStyleAttr, R.style.Widget_Design_TextInputLayout); if (a.hasValue(R.styleable.TextInputLayout_android_textColorHint)) { mDefaultTextColorResId = mFocusedTextColorResId = a.getResourceId(R.styleable.TextInputLayout_android_textColorHint, INVALID_ID); SkinLog.e(TAG, "mDefaultTextColorResId = " + mDefaultTextColorResId + ", hex = " + Integer.toHexString(getResources().getColor(mDefaultTextColorResId)) + ", res name = " + getResources().getResourceName(mDefaultTextColorResId)); applyFocusedTextColorResource(); } int errorTextAppearance = a.getResourceId(R.styleable.TextInputLayout_errorTextAppearance, INVALID_ID); loadErrorTextColorResFromAttributes(errorTextAppearance); int counterTextAppearance = a.getResourceId(R.styleable.TextInputLayout_counterTextAppearance, INVALID_ID); loadCounterTextColorResFromAttributes(counterTextAppearance); mPasswordToggleResId = a.getResourceId(R.styleable.TextInputLayout_passwordToggleDrawable, INVALID_ID); a.recycle(); } private void loadCounterTextColorResFromAttributes(@StyleRes int resId) { if (resId != INVALID_ID) { TintTypedArray counterTA = TintTypedArray.obtainStyledAttributes(getContext(), resId, skin.support.R.styleable.SkinTextAppearance); if (counterTA.hasValue(skin.support.R.styleable.SkinTextAppearance_android_textColor)) { mCounterTextColorResId = counterTA.getResourceId(skin.support.R.styleable.SkinTextAppearance_android_textColor, INVALID_ID); SkinLog.d(TAG, "mCounterTextColorResId name = " + getResources().getResourceName(mCounterTextColorResId)); } counterTA.recycle(); } applyCounterTextColorResource(); } @Override public void setCounterEnabled(boolean enabled) { super.setCounterEnabled(enabled); if (enabled) { applyCounterTextColorResource(); } } private void applyCounterTextColorResource() { mCounterTextColorResId = SkinCompatHelper.checkResourceId(mCounterTextColorResId); if (mCounterTextColorResId != INVALID_ID) { TextView counterView = getCounterView(); if (counterView != null) { // SkinLog.e(TAG, "mCounterTextColor = " +Integer.toHexString(SkinCompatResources.getInstance().getColor(mCounterTextColorResId))); counterView.setTextColor(SkinCompatResources.getInstance().getColor(mCounterTextColorResId)); updateEditTextBackground(); } } } private TextView getCounterView() { try { Field counterView = TextInputLayout.class.getDeclaredField("mCounterView"); counterView.setAccessible(true); return (TextView) counterView.get(this); } catch (Exception e) { e.printStackTrace(); } return null; } @Override public void setErrorTextAppearance(@StyleRes int resId) { super.setErrorTextAppearance(resId); loadErrorTextColorResFromAttributes(resId); } private void loadErrorTextColorResFromAttributes(@StyleRes int resId) { if (resId != INVALID_ID) { TintTypedArray errorTA = TintTypedArray.obtainStyledAttributes(getContext(), resId, skin.support.R.styleable.SkinTextAppearance); if (errorTA.hasValue(skin.support.R.styleable.SkinTextAppearance_android_textColor)) { mErrorTextColorResId = errorTA.getResourceId(skin.support.R.styleable.SkinTextAppearance_android_textColor, INVALID_ID); SkinLog.d(TAG, "mErrorTextColorResId = " + SkinCompatHelper.checkResourceId(mErrorTextColorResId)); } errorTA.recycle(); } applyErrorTextColorResource(); } @Override public void setErrorEnabled(boolean enabled) { super.setErrorEnabled(enabled); if (enabled) { applyErrorTextColorResource(); } } private void applyErrorTextColorResource() { mErrorTextColorResId = SkinCompatHelper.checkResourceId(mErrorTextColorResId); if (mErrorTextColorResId != INVALID_ID && mErrorTextColorResId != R.color.design_error) { TextView errorView = getErrorView(); if (errorView != null) { errorView.setTextColor(SkinCompatResources.getInstance().getColor(mErrorTextColorResId)); updateEditTextBackground(); } } } private TextView getErrorView() { try { Field errorView = TextInputLayout.class.getDeclaredField("mErrorView"); errorView.setAccessible(true); return (TextView) errorView.get(this); } catch (Exception e) { e.printStackTrace(); } return null; } private void updateEditTextBackground() { try { Method updateEditTextBackground = TextInputLayout.class.getDeclaredMethod("updateEditTextBackground"); updateEditTextBackground.setAccessible(true); updateEditTextBackground.invoke(this); } catch (Exception e) { e.printStackTrace(); } } private void setDefaultTextColor(ColorStateList colors) { try { Field defaultTextColor = TextInputLayout.class.getDeclaredField("mDefaultTextColor"); defaultTextColor.setAccessible(true); defaultTextColor.set(this, colors); updateLabelState(); } catch (Exception e) { e.printStackTrace(); } } private void applyFocusedTextColorResource() { mFocusedTextColorResId = SkinCompatHelper.checkResourceId(mFocusedTextColorResId); if (mFocusedTextColorResId != INVALID_ID && mFocusedTextColorResId != R.color.abc_hint_foreground_material_light) { setFocusedTextColor(SkinCompatResources.getInstance().getColorStateList(mFocusedTextColorResId)); } else if (getEditText() != null) { int textColorResId = INVALID_ID; if (getEditText() instanceof SkinCompatEditText) { textColorResId = ((SkinCompatEditText) getEditText()).getTextColorResId(); } else if (getEditText() instanceof SkinMaterialTextInputEditText) { textColorResId = ((SkinMaterialTextInputEditText) getEditText()).getTextColorResId(); } textColorResId = SkinCompatHelper.checkResourceId(textColorResId); if (textColorResId != INVALID_ID) { ColorStateList colors = SkinCompatResources.getInstance().getColorStateList(textColorResId); setFocusedTextColor(colors); } } } private void setFocusedTextColor(ColorStateList colors) { try { Field focusedTextcolor = TextInputLayout.class.getDeclaredField("mFocusedTextColor"); focusedTextcolor.setAccessible(true); focusedTextcolor.set(this, colors); updateLabelState(); } catch (Exception e) { e.printStackTrace(); } } private void updateLabelState() { try { Method updateLabelState = TextInputLayout.class.getDeclaredMethod("updateLabelState", boolean.class); updateLabelState.setAccessible(true); updateLabelState.invoke(this, false); } catch (Exception e) { e.printStackTrace(); } } @Override public void applySkin() { applyErrorTextColorResource(); applyCounterTextColorResource(); applyFocusedTextColorResource(); if (mBackgroundTintHelper != null) { mBackgroundTintHelper.applySkin(); } } }