Home | History | Annotate | Download | only in widget
      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