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.AutoCompleteTextView; 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 AutoCompleteTextView} which supports compatible features on older versions of the 39 * platform, including: 40 * <ul> 41 * <li>Allows dynamic tint of its background via the background tint methods in 42 * {@link androidx.core.view.ViewCompat}.</li> 43 * <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and 44 * {@link R.attr#backgroundTintMode}.</li> 45 * </ul> 46 * 47 * <p>This will automatically be used when you use {@link AutoCompleteTextView} in your layouts 48 * and the top-level activity / dialog is provided by 49 * <a href="{@docRoot}topic/libraries/support-library/packages.html#v7-appcompat">appcompat</a>. 50 * You should only need to manually use this class when writing custom views.</p> 51 */ 52 public class AppCompatAutoCompleteTextView extends AutoCompleteTextView implements 53 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 AppCompatAutoCompleteTextView(Context context)62 public AppCompatAutoCompleteTextView(Context context) { 63 this(context, null); 64 } 65 AppCompatAutoCompleteTextView(Context context, AttributeSet attrs)66 public AppCompatAutoCompleteTextView(Context context, AttributeSet attrs) { 67 this(context, attrs, R.attr.autoCompleteTextViewStyle); 68 } 69 AppCompatAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr)70 public AppCompatAutoCompleteTextView(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 setDropDownBackgroundResource(@rawableRes int resId)89 public void setDropDownBackgroundResource(@DrawableRes int resId) { 90 setDropDownBackgroundDrawable(AppCompatResources.getDrawable(getContext(), resId)); 91 } 92 93 @Override setBackgroundResource(@rawableRes int resId)94 public void setBackgroundResource(@DrawableRes int resId) { 95 super.setBackgroundResource(resId); 96 if (mBackgroundTintHelper != null) { 97 mBackgroundTintHelper.onSetBackgroundResource(resId); 98 } 99 } 100 101 @Override setBackgroundDrawable(Drawable background)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 setSupportBackgroundTintList(@ullable ColorStateList tint)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 getSupportBackgroundTintList()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 setSupportBackgroundTintMode(@ullable PorterDuff.Mode tintMode)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 getSupportBackgroundTintMode()160 public PorterDuff.Mode getSupportBackgroundTintMode() { 161 return mBackgroundTintHelper != null 162 ? mBackgroundTintHelper.getSupportBackgroundTintMode() : null; 163 } 164 165 @Override drawableStateChanged()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 setTextAppearance(Context context, int resId)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 onCreateInputConnection(EditorInfo outAttrs)185 public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 186 return AppCompatHintHelper.onCreateInputConnection(super.onCreateInputConnection(outAttrs), 187 outAttrs, this); 188 } 189 } 190