• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.text.Editable;
26 import android.util.AttributeSet;
27 import android.view.inputmethod.EditorInfo;
28 import android.view.inputmethod.InputConnection;
29 import android.widget.EditText;
30 
31 import androidx.annotation.DrawableRes;
32 import androidx.annotation.Nullable;
33 import androidx.annotation.RestrictTo;
34 import androidx.appcompat.R;
35 import androidx.core.os.BuildCompat;
36 import androidx.core.view.TintableBackgroundView;
37 
38 /**
39  * A {@link EditText} which supports compatible features on older versions of the platform,
40  * including:
41  * <ul>
42  *     <li>Allows dynamic tint of its background via the background tint methods in
43  *     {@link androidx.core.view.ViewCompat}.</li>
44  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
45  *     {@link R.attr#backgroundTintMode}.</li>
46  * </ul>
47  *
48  * <p>This will automatically be used when you use {@link EditText} in your layouts
49  * and the top-level activity / dialog is provided by
50  * <a href="{@docRoot}topic/libraries/support-library/packages.html#v7-appcompat">appcompat</a>.
51  * You should only need to manually use this class when writing custom views.</p>
52  */
53 public class AppCompatEditText extends EditText implements TintableBackgroundView {
54 
55     private final AppCompatBackgroundHelper mBackgroundTintHelper;
56     private final AppCompatTextHelper mTextHelper;
57 
AppCompatEditText(Context context)58     public AppCompatEditText(Context context) {
59         this(context, null);
60     }
61 
AppCompatEditText(Context context, AttributeSet attrs)62     public AppCompatEditText(Context context, AttributeSet attrs) {
63         this(context, attrs, R.attr.editTextStyle);
64     }
65 
AppCompatEditText(Context context, AttributeSet attrs, int defStyleAttr)66     public AppCompatEditText(Context context, AttributeSet attrs, int defStyleAttr) {
67         super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
68 
69         mBackgroundTintHelper = new AppCompatBackgroundHelper(this);
70         mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
71 
72         mTextHelper = new AppCompatTextHelper(this);
73         mTextHelper.loadFromAttributes(attrs, defStyleAttr);
74         mTextHelper.applyCompoundDrawablesTints();
75     }
76 
77     /**
78      * Return the text that the view is displaying. If an editable text has not been set yet, this
79      * will return null.
80      */
81     @Override
getText()82     @Nullable public Editable getText() {
83         if (BuildCompat.isAtLeastP()) {
84             return super.getText();
85         }
86         // A bug pre-P makes getText() crash if called before the first setText due to a cast, so
87         // retrieve the editable text.
88         return super.getEditableText();
89     }
90 
91     @Override
setBackgroundResource(@rawableRes int resId)92     public void setBackgroundResource(@DrawableRes int resId) {
93         super.setBackgroundResource(resId);
94         if (mBackgroundTintHelper != null) {
95             mBackgroundTintHelper.onSetBackgroundResource(resId);
96         }
97     }
98 
99     @Override
setBackgroundDrawable(Drawable background)100     public void setBackgroundDrawable(Drawable background) {
101         super.setBackgroundDrawable(background);
102         if (mBackgroundTintHelper != null) {
103             mBackgroundTintHelper.onSetBackgroundDrawable(background);
104         }
105     }
106 
107     /**
108      * This should be accessed via
109      * {@link androidx.core.view.ViewCompat#setBackgroundTintList(android.view.View, ColorStateList)}
110      *
111      * @hide
112      */
113     @RestrictTo(LIBRARY_GROUP)
114     @Override
setSupportBackgroundTintList(@ullable ColorStateList tint)115     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
116         if (mBackgroundTintHelper != null) {
117             mBackgroundTintHelper.setSupportBackgroundTintList(tint);
118         }
119     }
120 
121     /**
122      * This should be accessed via
123      * {@link androidx.core.view.ViewCompat#getBackgroundTintList(android.view.View)}
124      *
125      * @hide
126      */
127     @RestrictTo(LIBRARY_GROUP)
128     @Override
129     @Nullable
getSupportBackgroundTintList()130     public ColorStateList getSupportBackgroundTintList() {
131         return mBackgroundTintHelper != null
132                 ? mBackgroundTintHelper.getSupportBackgroundTintList() : null;
133     }
134 
135     /**
136      * This should be accessed via
137      * {@link androidx.core.view.ViewCompat#setBackgroundTintMode(android.view.View, PorterDuff.Mode)}
138      *
139      * @hide
140      */
141     @RestrictTo(LIBRARY_GROUP)
142     @Override
setSupportBackgroundTintMode(@ullable PorterDuff.Mode tintMode)143     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
144         if (mBackgroundTintHelper != null) {
145             mBackgroundTintHelper.setSupportBackgroundTintMode(tintMode);
146         }
147     }
148 
149     /**
150      * This should be accessed via
151      * {@link androidx.core.view.ViewCompat#getBackgroundTintMode(android.view.View)}
152      *
153      * @hide
154      */
155     @RestrictTo(LIBRARY_GROUP)
156     @Override
157     @Nullable
getSupportBackgroundTintMode()158     public PorterDuff.Mode getSupportBackgroundTintMode() {
159         return mBackgroundTintHelper != null
160                 ? mBackgroundTintHelper.getSupportBackgroundTintMode() : null;
161     }
162 
163     @Override
drawableStateChanged()164     protected void drawableStateChanged() {
165         super.drawableStateChanged();
166         if (mBackgroundTintHelper != null) {
167             mBackgroundTintHelper.applySupportBackgroundTint();
168         }
169         if (mTextHelper != null) {
170             mTextHelper.applyCompoundDrawablesTints();
171         }
172     }
173 
174     @Override
setTextAppearance(Context context, int resId)175     public void setTextAppearance(Context context, int resId) {
176         super.setTextAppearance(context, resId);
177         if (mTextHelper != null) {
178             mTextHelper.onSetTextAppearance(context, resId);
179         }
180     }
181 
182     @Override
onCreateInputConnection(EditorInfo outAttrs)183     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
184         return AppCompatHintHelper.onCreateInputConnection(super.onCreateInputConnection(outAttrs),
185                 outAttrs, this);
186     }
187 }
188