1 /* 2 * Copyright (C) 2014 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 androidx.appcompat.widget; 18 19 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20 21 import android.content.Context; 22 import android.content.res.ColorStateList; 23 import android.graphics.PorterDuff; 24 import android.graphics.drawable.Drawable; 25 import android.util.AttributeSet; 26 import android.view.inputmethod.EditorInfo; 27 import android.view.inputmethod.InputConnection; 28 import android.widget.MultiAutoCompleteTextView; 29 30 import androidx.annotation.DrawableRes; 31 import androidx.annotation.Nullable; 32 import androidx.annotation.RestrictTo; 33 import androidx.appcompat.R; 34 import androidx.appcompat.content.res.AppCompatResources; 35 import androidx.core.view.TintableBackgroundView; 36 37 /** 38 * A {@link MultiAutoCompleteTextView} which supports compatible features on older version of the 39 * platform, including: 40 * <ul> 41 * <li>Supports {@link R.attr#textAllCaps} style attribute which works back to 42 * {@link android.os.Build.VERSION_CODES#GINGERBREAD Gingerbread}.</li> 43 * <li>Allows dynamic tint of its background via the background tint methods in 44 * {@link androidx.core.view.ViewCompat}.</li> 45 * <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and 46 * {@link R.attr#backgroundTintMode}.</li> 47 * </ul> 48 * 49 * <p>This will automatically be used when you use {@link MultiAutoCompleteTextView} in your layouts. 50 * You should only need to manually use this class when writing custom views.</p> 51 */ 52 public class AppCompatMultiAutoCompleteTextView extends MultiAutoCompleteTextView 53 implements TintableBackgroundView { 54 55 private static final int[] TINT_ATTRS = { 56 android.R.attr.popupBackground 57 }; 58 59 private final AppCompatBackgroundHelper mBackgroundTintHelper; 60 private final AppCompatTextHelper mTextHelper; 61 62 public AppCompatMultiAutoCompleteTextView(Context context) { 63 this(context, null); 64 } 65 66 public AppCompatMultiAutoCompleteTextView(Context context, AttributeSet attrs) { 67 this(context, attrs, R.attr.autoCompleteTextViewStyle); 68 } 69 70 public AppCompatMultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) { 71 super(TintContextWrapper.wrap(context), attrs, defStyleAttr); 72 73 TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs, 74 TINT_ATTRS, defStyleAttr, 0); 75 if (a.hasValue(0)) { 76 setDropDownBackgroundDrawable(a.getDrawable(0)); 77 } 78 a.recycle(); 79 80 mBackgroundTintHelper = new AppCompatBackgroundHelper(this); 81 mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr); 82 83 mTextHelper = new AppCompatTextHelper(this); 84 mTextHelper.loadFromAttributes(attrs, defStyleAttr); 85 mTextHelper.applyCompoundDrawablesTints(); 86 } 87 88 @Override 89 public void setDropDownBackgroundResource(@DrawableRes int resId) { 90 setDropDownBackgroundDrawable(AppCompatResources.getDrawable(getContext(), resId)); 91 } 92 93 @Override 94 public void setBackgroundResource(@DrawableRes int resId) { 95 super.setBackgroundResource(resId); 96 if (mBackgroundTintHelper != null) { 97 mBackgroundTintHelper.onSetBackgroundResource(resId); 98 } 99 } 100 101 @Override 102 public void setBackgroundDrawable(Drawable background) { 103 super.setBackgroundDrawable(background); 104 if (mBackgroundTintHelper != null) { 105 mBackgroundTintHelper.onSetBackgroundDrawable(background); 106 } 107 } 108 109 /** 110 * This should be accessed via 111 * {@link androidx.core.view.ViewCompat#setBackgroundTintList(android.view.View, ColorStateList)} 112 * 113 * @hide 114 */ 115 @RestrictTo(LIBRARY_GROUP) 116 @Override 117 public void setSupportBackgroundTintList(@Nullable ColorStateList tint) { 118 if (mBackgroundTintHelper != null) { 119 mBackgroundTintHelper.setSupportBackgroundTintList(tint); 120 } 121 } 122 123 /** 124 * This should be accessed via 125 * {@link androidx.core.view.ViewCompat#getBackgroundTintList(android.view.View)} 126 * 127 * @hide 128 */ 129 @RestrictTo(LIBRARY_GROUP) 130 @Override 131 @Nullable 132 public ColorStateList getSupportBackgroundTintList() { 133 return mBackgroundTintHelper != null 134 ? mBackgroundTintHelper.getSupportBackgroundTintList() : null; 135 } 136 137 /** 138 * This should be accessed via 139 * {@link androidx.core.view.ViewCompat#setBackgroundTintMode(android.view.View, PorterDuff.Mode)} 140 * 141 * @hide 142 */ 143 @RestrictTo(LIBRARY_GROUP) 144 @Override 145 public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) { 146 if (mBackgroundTintHelper != null) { 147 mBackgroundTintHelper.setSupportBackgroundTintMode(tintMode); 148 } 149 } 150 151 /** 152 * This should be accessed via 153 * {@link androidx.core.view.ViewCompat#getBackgroundTintMode(android.view.View)} 154 * 155 * @hide 156 */ 157 @RestrictTo(LIBRARY_GROUP) 158 @Override 159 @Nullable 160 public PorterDuff.Mode getSupportBackgroundTintMode() { 161 return mBackgroundTintHelper != null 162 ? mBackgroundTintHelper.getSupportBackgroundTintMode() : null; 163 } 164 165 @Override 166 protected void drawableStateChanged() { 167 super.drawableStateChanged(); 168 if (mBackgroundTintHelper != null) { 169 mBackgroundTintHelper.applySupportBackgroundTint(); 170 } 171 if (mTextHelper != null) { 172 mTextHelper.applyCompoundDrawablesTints(); 173 } 174 } 175 176 @Override 177 public void setTextAppearance(Context context, int resId) { 178 super.setTextAppearance(context, resId); 179 if (mTextHelper != null) { 180 mTextHelper.onSetTextAppearance(context, resId); 181 } 182 } 183 184 @Override 185 public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 186 return AppCompatHintHelper.onCreateInputConnection(super.onCreateInputConnection(outAttrs), 187 outAttrs, this); 188 } 189 } 190