package com.time.cat.ui.widgets.theme.widgets; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.widget.SwitchCompat; import android.util.AttributeSet; import com.time.cat.ui.widgets.theme.utils.DrawableUtils; import com.time.cat.ui.widgets.theme.utils.ThemeUtils; import com.time.cat.ui.widgets.theme.utils.TintInfo; import com.time.cat.ui.widgets.theme.utils.TintManager; /** * @author dlink * @date 2018/1/25 * @discription */ public class AppCompatSwitchHelper { private int[] sAttrs; private SwitchCompat mSwitchCompat; private TintManager mTintManager; private boolean mSkipNextApply; private DrawableCallback mDrawableCallback; private TintInfo mTintInfo; private int mResId; private int mTintResId; private PorterDuff.Mode mTintMode; public AppCompatSwitchHelper(SwitchCompat switchCompat, TintManager tintManager, int[] attrs, @NonNull DrawableCallback callback) { this.sAttrs = attrs; this.mTintManager = tintManager; this.mSwitchCompat = switchCompat; this.mDrawableCallback = callback; } private boolean skipNextApply() { if (mSkipNextApply) { mSkipNextApply = false; return true; } mSkipNextApply = true; return false; } private void setSkipNextApply(boolean flag) { mSkipNextApply = flag; } @SuppressWarnings("ResourceType") public void loadFromAttribute(AttributeSet attrs, int defStyleAttr) { TypedArray array = mSwitchCompat.getContext().obtainStyledAttributes(attrs, sAttrs, defStyleAttr, 0); if (array.hasValue(1)) { mTintResId = array.getResourceId(1, 0); if (array.hasValue(2)) { setSupportDrawableTintMode(mTintMode = DrawableUtils.parseTintMode(array.getInt(2, 0), null)); } setSupportDrawableTint(mTintResId); } else { Drawable drawable = mTintManager.getDrawable(mResId = array.getResourceId(0, 0)); if (drawable != null) { setDrawable(drawable); } } array.recycle(); } /** * External use */ public void setDrawable() { if (skipNextApply()) return; resetTintResource(0); setSkipNextApply(false); } public void setDrawableId(int resId) { if (mResId != resId) { resetTintResource(resId); if (resId != 0) { Drawable drawable = mTintManager.getDrawable(resId); setDrawable(drawable != null ? drawable : ContextCompat.getDrawable(mSwitchCompat.getContext(), resId)); } } } public void setDrawableTintList(ColorStateList origin) { ColorStateList tint = ThemeUtils.getThemeColorStateList(mSwitchCompat.getContext(), origin); if (mTintInfo == null) { mTintInfo = new TintInfo(); } mTintInfo.mHasTintList = true; mTintInfo.mTintList = tint; applySupportDrawableTint(); } public void setDrawableTintMode(PorterDuff.Mode mode) { if (mode != null && mode != mTintMode) { if (mTintInfo != null) { mTintInfo.mHasTintList = false; mTintInfo.mTintList = null; } setSupportDrawableTintMode(mode); setSupportDrawableTint(mTintResId); } } public void setButtonDrawableTintList(int resId, PorterDuff.Mode mode) { if (mTintResId != resId) { mTintResId = resId; if (mTintInfo != null) { mTintInfo.mHasTintList = false; mTintInfo.mTintList = null; mTintInfo.mHasTintMode = false; mTintInfo.mTintMode = null; } setSupportDrawableTintMode(mode); setSupportDrawableTint(resId); } } /** * Internal use */ private void setDrawable(Drawable drawable) { if (skipNextApply()) return; mDrawableCallback.setDrawable(drawable); } private boolean setSupportDrawableTint(int resId) { if (resId != 0) { if (mTintInfo == null) { mTintInfo = new TintInfo(); } mTintInfo.mHasTintList = true; mTintInfo.mTintList = mTintManager.getColorStateList(resId); } return applySupportDrawableTint(); } private void setSupportDrawableTintMode(PorterDuff.Mode mode) { if (mode != null) { if (mTintInfo == null) { mTintInfo = new TintInfo(); } mTintInfo.mHasTintMode = true; mTintInfo.mTintMode = mode; } } private boolean applySupportDrawableTint() { Drawable drawable = mDrawableCallback.getDrawable(); if (drawable != null && mTintInfo != null && mTintInfo.mHasTintList) { Drawable tintDrawable = drawable.mutate(); tintDrawable = DrawableCompat.wrap(tintDrawable); if (mTintInfo.mHasTintList) { DrawableCompat.setTintList(tintDrawable, mTintInfo.mTintList); } if (mTintInfo.mHasTintMode) { DrawableCompat.setTintMode(tintDrawable, mTintInfo.mTintMode); } if (tintDrawable.isStateful()) { tintDrawable.setState(mSwitchCompat.getDrawableState()); } setDrawable(tintDrawable); if (drawable == tintDrawable) { tintDrawable.invalidateSelf(); } return true; } return false; } private void resetTintResource(int resId/*background resource id*/) { mResId = resId; mTintResId = 0; mTintMode = null; if (mTintInfo != null) { mTintInfo.mHasTintList = false; mTintInfo.mTintList = null; mTintInfo.mHasTintMode = false; mTintInfo.mTintMode = null; } } public void tint() { if (mTintResId == 0 || !setSupportDrawableTint(mTintResId)) { Drawable drawable = mTintManager.getDrawable(mResId); if (drawable == null) { drawable = mResId == 0 ? null : ContextCompat.getDrawable(mSwitchCompat.getContext(), mResId); } setDrawable(drawable); } } public interface DrawableCallback { Drawable getDrawable(); void setDrawable(Drawable drawable); } public interface SwitchCompatExtensible { void setTrackTintList(int resId); void setTrackTintList(int resId, PorterDuff.Mode mode); void setThumbTintList(int resId); void setThumbTintList(int resId, PorterDuff.Mode mode); } }