• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.support.v7.widget;
18 
19 import android.content.res.ColorStateList;
20 import android.content.res.TypedArray;
21 import android.graphics.PorterDuff;
22 import android.graphics.drawable.Drawable;
23 import android.os.Build;
24 import android.support.annotation.Nullable;
25 import android.support.v4.graphics.drawable.DrawableCompat;
26 import android.support.v4.widget.CompoundButtonCompat;
27 import android.support.v7.appcompat.R;
28 import android.support.v7.graphics.drawable.DrawableUtils;
29 import android.support.v7.internal.widget.TintManager;
30 import android.util.AttributeSet;
31 import android.widget.CompoundButton;
32 
33 class AppCompatCompoundButtonHelper {
34 
35     private final CompoundButton mView;
36     private final TintManager mTintManager;
37 
38     private ColorStateList mButtonTintList = null;
39     private PorterDuff.Mode mButtonTintMode = null;
40     private boolean mHasButtonTint = false;
41     private boolean mHasButtonTintMode = false;
42 
43     private boolean mSkipNextApply;
44 
45     /**
46      * Interface which allows us to directly set a button, bypass any calls back to ourselves.
47      */
48     interface DirectSetButtonDrawableInterface {
setButtonDrawable(Drawable buttonDrawable)49         void setButtonDrawable(Drawable buttonDrawable);
50     }
51 
AppCompatCompoundButtonHelper(CompoundButton view, TintManager tintManager)52     AppCompatCompoundButtonHelper(CompoundButton view, TintManager tintManager) {
53         mView = view;
54         mTintManager = tintManager;
55     }
56 
loadFromAttributes(AttributeSet attrs, int defStyleAttr)57     void loadFromAttributes(AttributeSet attrs, int defStyleAttr) {
58         TypedArray a = mView.getContext().obtainStyledAttributes(attrs, R.styleable.CompoundButton,
59                 defStyleAttr, 0);
60         try {
61             if (a.hasValue(R.styleable.CompoundButton_android_button)) {
62                 final int resourceId = a.getResourceId(
63                         R.styleable.CompoundButton_android_button, 0);
64                 if (resourceId != 0) {
65                     mView.setButtonDrawable(mTintManager.getDrawable(resourceId));
66                 }
67             }
68             if (a.hasValue(R.styleable.CompoundButton_buttonTint)) {
69                 CompoundButtonCompat.setButtonTintList(mView,
70                         a.getColorStateList(R.styleable.CompoundButton_buttonTint));
71             }
72             if (a.hasValue(R.styleable.CompoundButton_buttonTintMode)) {
73                 CompoundButtonCompat.setButtonTintMode(mView,
74                         DrawableUtils.parseTintMode(
75                                 a.getInt(R.styleable.CompoundButton_buttonTintMode, -1),
76                                 null));
77             }
78         } finally {
79             a.recycle();
80         }
81     }
82 
setSupportButtonTintList(ColorStateList tint)83     void setSupportButtonTintList(ColorStateList tint) {
84         mButtonTintList = tint;
85         mHasButtonTint = true;
86 
87         applyButtonTint();
88     }
89 
getSupportButtonTintList()90     ColorStateList getSupportButtonTintList() {
91         return mButtonTintList;
92     }
93 
setSupportButtonTintMode(@ullable PorterDuff.Mode tintMode)94     void setSupportButtonTintMode(@Nullable PorterDuff.Mode tintMode) {
95         mButtonTintMode = tintMode;
96         mHasButtonTintMode = true;
97 
98         applyButtonTint();
99     }
100 
getSupportButtonTintMode()101     PorterDuff.Mode getSupportButtonTintMode() {
102         return mButtonTintMode;
103     }
104 
onSetButtonDrawable()105     void onSetButtonDrawable() {
106         if (mSkipNextApply) {
107             mSkipNextApply = false;
108             return;
109         }
110 
111         mSkipNextApply = true;
112         applyButtonTint();
113     }
114 
applyButtonTint()115     void applyButtonTint() {
116         Drawable buttonDrawable = CompoundButtonCompat.getButtonDrawable(mView);
117 
118         if (buttonDrawable != null && (mHasButtonTint || mHasButtonTintMode)) {
119             buttonDrawable = DrawableCompat.wrap(buttonDrawable);
120             buttonDrawable = buttonDrawable.mutate();
121             if (mHasButtonTint) {
122                 DrawableCompat.setTintList(buttonDrawable, mButtonTintList);
123             }
124             if (mHasButtonTintMode) {
125                 DrawableCompat.setTintMode(buttonDrawable, mButtonTintMode);
126             }
127             // The drawable (or one of its children) may not have been
128             // stateful before applying the tint, so let's try again.
129             if (buttonDrawable.isStateful()) {
130                 buttonDrawable.setState(mView.getDrawableState());
131             }
132             mView.setButtonDrawable(buttonDrawable);
133         }
134     }
135 
getCompoundPaddingLeft(int superValue)136     int getCompoundPaddingLeft(int superValue) {
137         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
138             // Before JB-MR1 the button drawable wasn't taken into account for padding. We'll
139             // workaround that here
140             Drawable buttonDrawable = CompoundButtonCompat.getButtonDrawable(mView);
141             if (buttonDrawable != null) {
142                 superValue += buttonDrawable.getIntrinsicWidth();
143             }
144         }
145         return superValue;
146     }
147 }
148