Java tutorial
/* * Copyright (C) 2006 The Android Open Source Project * * 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.tencent.tws.assistant.widget; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.PorterDuff; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.support.annotation.DrawableRes; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import com.tencent.tws.assistant.drawable.TwsAnimatedStateListDrawable; import com.tencent.tws.assistant.drawable.TwsRippleDrawable; import com.tencent.tws.assistant.support.v4.widget.TintableCompoundButton; import com.tencent.tws.assistant.utils.ThemeUtils; import com.tencent.tws.sharelib.R; /** * A {@link CheckBox} which supports compatible features on older version of the platform, including: * <ul> * <li>Allows dynamic tint of it background via the background tint methods in * {@link android.support.v4.widget.CompoundButtonCompat}.</li> * <li>Allows setting of the background tint using {@link R.attr#buttonTint} and {@link R.attr#buttonTintMode} * .</li> * </ul> * * <p> * This will automatically be used when you use {@link CheckBox} in your layouts. You should only need to * manually use this class when writing custom views. * </p> */ public class CheckBox extends android.widget.CheckBox implements TintableCompoundButton { private TintManager mTintManager; private CompoundButtonHelper mCompoundButtonHelper; private boolean mIsAnimationButton = true; final int[] checkOnDisableState = { android.R.attr.state_checked, -android.R.attr.state_enabled }; final int checkOnDisableResId = R.drawable.btn_check_on_disabled_holo_light; final int[] checkOffDisableState = { -android.R.attr.state_checked, -android.R.attr.state_enabled }; final int checkOffDisableResId = R.drawable.btn_check_off_disabled_holo_light; final int[] checkOnState = { android.R.attr.state_checked, android.R.attr.state_enabled }; final int checkOnResId = R.drawable.btn_check_to_on_mtrl_007; final int[] checkOffState = { -android.R.attr.state_checked, android.R.attr.state_enabled }; final int checkOffResId = R.drawable.btn_check_to_on_mtrl_000; final int checkOnkeyframeId = R.id.on; final int checkOffKeyframeId = R.id.off; final int checkToOnResId = R.drawable.btn_check_to_on_material_anim; final int checkToOffResId = R.drawable.btn_check_to_off_material_anim; private Drawable mAnimationButtonDrawable = null; private boolean mIsSupportTintDrawable = false; private int mColorControlActivated = 0; public CheckBox(Context context) { this(context, null); } public CheckBox(Context context, AttributeSet attrs) { this(context, attrs, R.attr.checkboxStyle); } public CheckBox(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); if (mIsAnimationButton) { setAnimationButtonDrawable(mIsAnimationButton); } else { mTintManager = TintManager.get(context); mCompoundButtonHelper = new CompoundButtonHelper(this, mTintManager); mCompoundButtonHelper.loadFromAttributes(attrs, defStyleAttr); } } @Override public void setButtonDrawable(Drawable buttonDrawable) { super.setButtonDrawable(buttonDrawable); if (mCompoundButtonHelper != null && !mIsAnimationButton) { mCompoundButtonHelper.onSetButtonDrawable(); } } @Override public void setButtonDrawable(@DrawableRes int resId) { setButtonDrawable(mTintManager != null ? mTintManager.getDrawable(resId) : getContext().getResources().getDrawable(resId)); } @Override public int getCompoundPaddingLeft() { final int value = super.getCompoundPaddingLeft(); return mCompoundButtonHelper != null ? mCompoundButtonHelper.getCompoundPaddingLeft(value) : value; } /** * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat} * * @hide */ @Override public void setSupportButtonTintList(@Nullable ColorStateList tint) { if (mCompoundButtonHelper != null) { mCompoundButtonHelper.setSupportButtonTintList(tint); } } /** * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat} * * @hide */ @Nullable @Override public ColorStateList getSupportButtonTintList() { return mCompoundButtonHelper != null ? mCompoundButtonHelper.getSupportButtonTintList() : null; } /** * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat} * * @hide */ @Override public void setSupportButtonTintMode(@Nullable PorterDuff.Mode tintMode) { if (mCompoundButtonHelper != null) { mCompoundButtonHelper.setSupportButtonTintMode(tintMode); } } /** * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat} * * @hide */ @Nullable @Override public PorterDuff.Mode getSupportButtonTintMode() { return mCompoundButtonHelper != null ? mCompoundButtonHelper.getSupportButtonTintMode() : null; } public void setAnimationButtonDrawable(boolean isAnimation) { if (isAnimation) { int colorControlNormal = ThemeUtils.getThemeAttrColor(getContext(), R.attr.colorControlNormal); int colorControlActivated = ThemeUtils.getThemeAttrColor(getContext(), R.attr.colorControlActivated); int colorControlDisabled = ThemeUtils.getDisabledThemeAttrColor(getContext(), R.attr.colorControlNormal); int colorControlActivateDisabled = ThemeUtils.getDisabledThemeAttrColor(getContext(), R.attr.colorControlActivated); if (colorControlNormal == 0) { colorControlNormal = getContext().getResources().getColor(R.color.control_normal_color); } if (colorControlActivated == 0) { colorControlActivated = getContext().getResources().getColor(R.color.control_activated_color); } if (colorControlDisabled == 0) { colorControlDisabled = getContext().getResources().getColor(R.color.control_disabled_color); } if (colorControlActivateDisabled == 0) { colorControlActivateDisabled = getContext().getResources() .getColor(R.color.control_activate_disabled_color); } setTintButtonDrawable(colorControlNormal, colorControlDisabled, colorControlActivated, colorControlActivateDisabled); } } @Override public void setVisibility(int visibility) { super.setVisibility(visibility); setAnimationButtonDrawable(View.VISIBLE == visibility); } public void setTintButtonDrawable(int colorStateList) { ColorStateList stateList = getContext().getResources().getColorStateList(colorStateList); if (stateList != null) { setTintButtonDrawable(stateList); } } public void setTintButtonDrawable(ColorStateList colorStateList) { mIsAnimationButton = true; int colorControlNormal = 0; int colorControlDisabled = 0; int colorControlActivated = 0; int colorControlActivateDisabled = 0; if (colorStateList.isStateful()) { colorControlNormal = colorStateList.getColorForState(checkOffState, colorStateList.getDefaultColor()); colorControlDisabled = colorStateList.getColorForState(checkOffDisableState, colorStateList.getDefaultColor()); colorControlActivated = colorStateList.getColorForState(checkOnState, colorStateList.getDefaultColor()); colorControlActivateDisabled = colorStateList.getColorForState(checkOnDisableState, colorStateList.getDefaultColor()); } setTintButtonDrawable(colorControlNormal, colorControlDisabled, colorControlActivated, colorControlActivateDisabled); } private void setTintButtonDrawable(int colorControlNormal, int colorControlDisabled, int colorControlActivated, int colorControlActivateDisabled) { final PorterDuff.Mode DEFAULT_MODE = PorterDuff.Mode.SRC_IN; final boolean isSupportTintDrawable = ThemeUtils.isSupportTintDrawable(getContext()); TwsAnimatedStateListDrawable drawable = new TwsAnimatedStateListDrawable(); Drawable checkOffDisableDrawable = getResources().getDrawable(checkOffDisableResId); Drawable checkOnDisableDrawable = getResources().getDrawable(checkOnDisableResId); Drawable checkOffDrawable = getResources().getDrawable(checkOffResId); Drawable checkOnDrawable = getResources().getDrawable(checkOnResId); if (isSupportTintDrawable) { checkOffDisableDrawable.setColorFilter(colorControlDisabled, DEFAULT_MODE); checkOnDisableDrawable.setColorFilter(colorControlActivateDisabled, DEFAULT_MODE); checkOffDrawable.setColorFilter(colorControlNormal, DEFAULT_MODE); checkOnDrawable.setColorFilter(colorControlActivated, DEFAULT_MODE); } drawable.addState(checkOffDisableState, checkOffDisableDrawable, 0); drawable.addState(checkOnDisableState, checkOnDisableDrawable, 0); drawable.addState(checkOffState, checkOffDrawable, checkOffKeyframeId); drawable.addState(checkOnState, checkOnDrawable, checkOnkeyframeId); AnimationDrawable toOnDrawable = (AnimationDrawable) getResources().getDrawable(checkToOnResId); AnimationDrawable toOffDrawable = (AnimationDrawable) getResources().getDrawable(checkToOffResId); if (isSupportTintDrawable) { toOnDrawable.setColorFilter(colorControlActivated, DEFAULT_MODE); toOffDrawable.setColorFilter(colorControlNormal, DEFAULT_MODE); } drawable.addTransition(checkOffKeyframeId, checkOnkeyframeId, toOnDrawable, false); drawable.addTransition(checkOnkeyframeId, checkOffKeyframeId, toOffDrawable, false); setButtonDrawable(drawable); mIsSupportTintDrawable = isSupportTintDrawable; mColorControlActivated = colorControlActivated; mAnimationButtonDrawable = drawable; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); setRippleBackground(mIsSupportTintDrawable, mAnimationButtonDrawable, mColorControlActivated); } private void setRippleBackground(boolean isSupportTintDrawable, Drawable orgDrawable, int rippleColor) { if (orgDrawable != null && isSupportTintDrawable) { ColorStateList csl = createNormalStateList(rippleColor); final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK; final int drawableHeight = orgDrawable.getIntrinsicHeight(); final int drawableWidth = orgDrawable.getIntrinsicWidth(); final float scale = 0.3f; final float drawableScaleHeight = drawableHeight * scale; final float drawableScaleWidth = drawableWidth * scale; final int top; switch (verticalGravity) { case Gravity.BOTTOM: top = (int) (getHeight() - drawableHeight - drawableScaleHeight); break; case Gravity.CENTER_VERTICAL: top = (int) (((getHeight() - drawableHeight) / 2) - drawableScaleHeight); break; default: top = (int) (-drawableScaleHeight); } final int bottom = (int) (top + drawableHeight + drawableScaleHeight * 2); final int left = (int) (isLayoutRtl() ? getWidth() - drawableWidth - drawableScaleWidth : -drawableScaleWidth); final int right = (int) (isLayoutRtl() ? getWidth() + drawableScaleWidth : drawableWidth + drawableScaleWidth); TwsRippleDrawable rippleDrawable = new TwsRippleDrawable(csl, null, null, TwsRippleDrawable.RIPPLE_STYLE_RING); rippleDrawable.twsSetHotspotBounds(left, top, right, bottom); setBackgroundDrawable(rippleDrawable); } } private ColorStateList createNormalStateList(int textColor) { // Now create a new ColorStateList with the default color final int[][] states = new int[1][]; final int[] colors = new int[1]; // Default state states[0] = EMPTY_STATE_SET; colors[0] = textColor; return new ColorStateList(states, colors); } }