1091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes/* 2091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Copyright (C) 2015 The Android Open Source Project 3091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 4091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 5091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * you may not use this file except in compliance with the License. 6091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * You may obtain a copy of the License at 7091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 8091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * http://www.apache.org/licenses/LICENSE-2.0 9091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 10091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Unless required by applicable law or agreed to in writing, software 11091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 12091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * See the License for the specific language governing permissions and 14091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * limitations under the License. 15091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 16091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 17091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banespackage android.support.v4.widget; 18091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 19091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.content.Context; 20091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.content.res.ColorStateList; 21091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.graphics.Canvas; 22091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.graphics.PorterDuff; 23091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.graphics.drawable.Drawable; 24091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.os.Build; 25091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.support.annotation.NonNull; 26091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.support.annotation.Nullable; 27091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.support.v4.graphics.drawable.DrawableCompat; 28091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.widget.CompoundButton; 29091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 30091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes/** 31091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Helper for accessing {@link android.widget.CompoundButton} methods introduced after 32091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * API level 4 in a backwards compatible fashion. 33091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 34091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banespublic final class CompoundButtonCompat { 35091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 36091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes private static final CompoundButtonCompatImpl IMPL; 37091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 38091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes static { 39091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes final int sdk = Build.VERSION.SDK_INT; 40080abff1400d6461206a6dc367411115590abda9Adam Powell if (sdk >= 23) { 41091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes IMPL = new Api23CompoundButtonImpl(); 42091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } else if (sdk >= 21) { 43091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes IMPL = new LollipopCompoundButtonImpl(); 44091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } else { 45091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes IMPL = new BaseCompoundButtonCompat(); 46091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 47091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 48091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 49091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes interface CompoundButtonCompatImpl { 50091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes void setButtonTintList(CompoundButton button, ColorStateList tint); 51091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes ColorStateList getButtonTintList(CompoundButton button); 52091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes void setButtonTintMode(CompoundButton button, PorterDuff.Mode tintMode); 53091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes PorterDuff.Mode getButtonTintMode(CompoundButton button); 54091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes Drawable getButtonDrawable(CompoundButton button); 55091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 56091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 57091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes static class BaseCompoundButtonCompat implements CompoundButtonCompatImpl { 58091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 59091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public void setButtonTintList(CompoundButton button, ColorStateList tint) { 60091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes CompoundButtonCompatDonut.setButtonTintList(button, tint); 61091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 62091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 63091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 64091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public ColorStateList getButtonTintList(CompoundButton button) { 65091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return CompoundButtonCompatDonut.getButtonTintList(button); 66091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 67091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 68091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 69091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public void setButtonTintMode(CompoundButton button, PorterDuff.Mode tintMode) { 70091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes CompoundButtonCompatDonut.setButtonTintMode(button, tintMode); 71091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 72091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 73091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 74091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public PorterDuff.Mode getButtonTintMode(CompoundButton button) { 75091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return CompoundButtonCompatDonut.getButtonTintMode(button); 76091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 77091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 78091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 79091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public Drawable getButtonDrawable(CompoundButton button) { 80091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return CompoundButtonCompatDonut.getButtonDrawable(button); 81091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 82091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 83091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 84091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes static class LollipopCompoundButtonImpl extends BaseCompoundButtonCompat { 85091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 86091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public void setButtonTintList(CompoundButton button, ColorStateList tint) { 87091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes CompoundButtonCompatLollipop.setButtonTintList(button, tint); 88091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 89091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 90091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 91091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public ColorStateList getButtonTintList(CompoundButton button) { 92091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return CompoundButtonCompatLollipop.getButtonTintList(button); 93091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 94091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 95091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 96091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public void setButtonTintMode(CompoundButton button, PorterDuff.Mode tintMode) { 97091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes CompoundButtonCompatLollipop.setButtonTintMode(button, tintMode); 98091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 99091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 100091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 101091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public PorterDuff.Mode getButtonTintMode(CompoundButton button) { 102091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return CompoundButtonCompatLollipop.getButtonTintMode(button); 103091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 104091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 105091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 106091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes static class Api23CompoundButtonImpl extends LollipopCompoundButtonImpl { 107091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 108091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public Drawable getButtonDrawable(CompoundButton button) { 109091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return CompoundButtonCompatApi23.getButtonDrawable(button); 110091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 111091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 112091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 113091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes private CompoundButtonCompat() {} 114091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 115091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes /** 116091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Applies a tint to the button drawable. Does not modify the current tint 117091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. 118091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * <p> 119091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Subsequent calls to {@link CompoundButton#setButtonDrawable(Drawable)} should 120091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * automatically mutate the drawable and apply the specified tint and tint 121091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * mode using {@link DrawableCompat#setTintList(Drawable, ColorStateList)}. 122091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 123091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @param tint the tint to apply, may be {@code null} to clear tint 124091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 125091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @see #setButtonTintList(CompoundButton, ColorStateList) 126091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 127091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public static void setButtonTintList(@NonNull CompoundButton button, @Nullable ColorStateList tint) { 128091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes IMPL.setButtonTintList(button, tint); 129091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 130091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 131091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes /** 132091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Returns the tint applied to the button drawable 133091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 134091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @see #setButtonTintList(CompoundButton, ColorStateList) 135091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 136091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Nullable 137091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public static ColorStateList getButtonTintList(@NonNull CompoundButton button) { 138091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return IMPL.getButtonTintList(button); 139091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 140091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 141091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes /** 142091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Specifies the blending mode used to apply the tint specified by 143091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * {@link #setButtonTintList(CompoundButton, ColorStateList)}} to the button drawable. The 144091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * default mode is {@link PorterDuff.Mode#SRC_IN}. 145091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 146091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @param tintMode the blending mode used to apply the tint, may be 147091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * {@code null} to clear tint 148091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 149091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @see #getButtonTintMode(CompoundButton) 150091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @see DrawableCompat#setTintMode(Drawable, PorterDuff.Mode) 151091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 152091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public static void setButtonTintMode(@NonNull CompoundButton button, 153091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Nullable PorterDuff.Mode tintMode) { 154091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes IMPL.setButtonTintMode(button, tintMode); 155091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 156091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 157091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes /** 158091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @return the blending mode used to apply the tint to the button drawable 159091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @attr ref android.R.styleable#CompoundButton_buttonTintMode 160091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @see #setButtonTintMode(PorterDuff.Mode) 161091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 162091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Nullable 163091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public static PorterDuff.Mode getButtonTintMode(@NonNull CompoundButton button) { 164091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return IMPL.getButtonTintMode(button); 165091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 166091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes 167091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes /** 168091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Returns the drawable used as the compound button image 169091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 170091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * @see CompoundButton#setButtonDrawable(Drawable) 171091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 172091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Nullable 173091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public static Drawable getButtonDrawable(@NonNull CompoundButton button) { 174091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return IMPL.getButtonDrawable(button); 175091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 176091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes} 177