1a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes/* 2a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * Copyright (C) 2014 The Android Open Source Project 3a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * 4a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 5a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * you may not use this file except in compliance with the License. 6a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * You may obtain a copy of the License at 7a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * 8a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 9a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * 10a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * Unless required by applicable law or agreed to in writing, software 11a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 12a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * See the License for the specific language governing permissions and 14a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes * limitations under the License. 15a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes */ 16a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 172cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banespackage android.support.v7.widget; 18a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 19a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banesimport android.content.Context; 20a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.content.res.ColorStateList; 21a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.graphics.PorterDuff; 22684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banesimport android.graphics.drawable.Drawable; 23091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banesimport android.support.annotation.DrawableRes; 24a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.support.annotation.Nullable; 25a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.support.v4.view.TintableBackgroundView; 262cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.appcompat.R; 272cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.text.AllCapsTransformationMethod; 282cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.widget.TintManager; 29a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banesimport android.util.AttributeSet; 302cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.view.accessibility.AccessibilityEvent; 312cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.view.accessibility.AccessibilityNodeInfo; 32a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banesimport android.widget.Button; 33a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 34a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes/** 35091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * A {@link Button} which supports compatible features on older version of the platform, 36091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * including: 37091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * <ul> 38091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * <li>Supports {@link R.attr#textAllCaps} style attribute which works back to 39091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * {@link android.os.Build.VERSION_CODES#ECLAIR_MR1 Eclair MR1}.</li> 40091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * <li>Allows dynamic tint of it background via the background tint methods in 41091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * {@link android.support.v4.view.ViewCompat}.</li> 42091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and 43091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * {@link R.attr#backgroundTintMode}.</li> 44091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * </ul> 45091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 46091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * <p>This will automatically be used when you use {@link android.widget.Button} in your 47091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * layouts. You should only need to manually use this class when writing custom views.</p> 48a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes */ 492cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banespublic class AppCompatButton extends Button implements TintableBackgroundView { 50a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 51091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes private final TintManager mTintManager; 52091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes private final AppCompatBackgroundHelper mBackgroundTintHelper; 53091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes private final AppCompatTextHelper mTextHelper; 54a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 552cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes public AppCompatButton(Context context) { 56a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes this(context, null); 57a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes } 58a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 592cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes public AppCompatButton(Context context, AttributeSet attrs) { 602cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes this(context, attrs, R.attr.buttonStyle); 61a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes } 62a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 632cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes public AppCompatButton(Context context, AttributeSet attrs, int defStyleAttr) { 64a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes super(context, attrs, defStyleAttr); 65a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 66091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mTintManager = TintManager.get(getContext()); 67091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mBackgroundTintHelper = new AppCompatBackgroundHelper(this, mTintManager); 68091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr); 69a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes 70091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mTextHelper = new AppCompatTextHelper(this); 71091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mTextHelper.loadFromAttributes(attrs, defStyleAttr); 72a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes } 73a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 74684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes @Override 75091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public void setBackgroundResource(@DrawableRes int resId) { 76684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes super.setBackgroundResource(resId); 77091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes if (mBackgroundTintHelper != null) { 78091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mBackgroundTintHelper.onSetBackgroundResource(resId); 79091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 80684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes } 81684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes 82684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes @Override 83684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes public void setBackgroundDrawable(Drawable background) { 84684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes super.setBackgroundDrawable(background); 85091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes if (mBackgroundTintHelper != null) { 86091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mBackgroundTintHelper.onSetBackgroundDrawable(background); 87091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes } 88684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes } 89684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes 90a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes /** 91a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * This should be accessed via 92091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * {@link android.support.v4.view.ViewCompat#setBackgroundTintList(android.view.View, ColorStateList)} 93a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * 94a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * @hide 95a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes */ 96a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes @Override 97a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes public void setSupportBackgroundTintList(@Nullable ColorStateList tint) { 98091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes if (mBackgroundTintHelper != null) { 99091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mBackgroundTintHelper.setSupportBackgroundTintList(tint); 100fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes } 101a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes } 102a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes 103a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes /** 104a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * This should be accessed via 105a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * {@link android.support.v4.view.ViewCompat#getBackgroundTintList(android.view.View)} 106a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * 107a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * @hide 108a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes */ 109a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes @Override 110a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes @Nullable 111a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes public ColorStateList getSupportBackgroundTintList() { 112091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return mBackgroundTintHelper != null 113091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes ? mBackgroundTintHelper.getSupportBackgroundTintList() : null; 114a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes } 115a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes 116a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes /** 117a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * This should be accessed via 118091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * {@link android.support.v4.view.ViewCompat#setBackgroundTintMode(android.view.View, PorterDuff.Mode)} 119a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * 120a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * @hide 121a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes */ 122a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes @Override 123a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) { 124091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes if (mBackgroundTintHelper != null) { 125091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mBackgroundTintHelper.setSupportBackgroundTintMode(tintMode); 126a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes } 127a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes } 128a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes 129a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes /** 130a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * This should be accessed via 131a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * {@link android.support.v4.view.ViewCompat#getBackgroundTintMode(android.view.View)} 132a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * 133a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes * @hide 134a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes */ 135a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes @Override 136a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes @Nullable 137a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes public PorterDuff.Mode getSupportBackgroundTintMode() { 138091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes return mBackgroundTintHelper != null 139091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes ? mBackgroundTintHelper.getSupportBackgroundTintMode() : null; 140a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes } 141a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes 142a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes @Override 143a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes protected void drawableStateChanged() { 144a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes super.drawableStateChanged(); 145091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes if (mBackgroundTintHelper != null) { 146091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mBackgroundTintHelper.applySupportBackgroundTint(); 147684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes } 148684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes } 149684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes 150091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes @Override 151091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public void setTextAppearance(Context context, int resId) { 152091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes super.setTextAppearance(context, resId); 153091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes if (mTextHelper != null) { 154091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mTextHelper.onSetTextAppearance(context, resId); 155fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes } 156a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes } 157a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes 1582cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes @Override 1592cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 1602cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes super.onInitializeAccessibilityEvent(event); 1612cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes event.setClassName(Button.class.getName()); 1622cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes } 1632cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes 1642cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes @Override 1652cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 1662cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes super.onInitializeAccessibilityNodeInfo(info); 1672cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes info.setClassName(Button.class.getName()); 1682cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes } 1692cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes 170091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes /** 171091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * Sets the properties of this field to transform input to ALL CAPS 172091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * display. This may use a "small caps" formatting if available. 173091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * This setting will be ignored if this field is editable or selectable. 174091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * 175091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * This call replaces the current transformation method. Disabling this 176091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * will not necessarily restore the previous behavior from before this 177091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes * was enabled. 178091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes */ 179091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes public void setSupportAllCaps(boolean allCaps) { 180091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes if (mTextHelper != null) { 181091b0f935e68ce9bfecc2422e60eada33fa3b09cChris Banes mTextHelper.setAllCaps(allCaps); 1822cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes } 1832cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes } 184a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes} 185