AppCompatEditText.java revision 684dbfaf7105761b5a19a82e8273ed79d3b0641e
1469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes/*
2469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * Copyright (C) 2014 The Android Open Source Project
3469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes *
4469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
5469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * you may not use this file except in compliance with the License.
6469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * You may obtain a copy of the License at
7469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes *
8469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
9469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes *
10469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * Unless required by applicable law or agreed to in writing, software
11469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
12469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * See the License for the specific language governing permissions and
14469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes * limitations under the License.
15469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes */
16469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
172cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banespackage android.support.v7.widget;
18469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
19469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.content.Context;
20a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.content.res.ColorStateList;
21a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.graphics.PorterDuff;
22684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banesimport android.graphics.drawable.Drawable;
23a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.support.annotation.Nullable;
24a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banesimport android.support.v4.view.TintableBackgroundView;
252cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.appcompat.R;
262cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.widget.TintContextWrapper;
272cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.widget.TintInfo;
282cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.widget.TintManager;
292cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.widget.TintTypedArray;
30469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.util.AttributeSet;
31469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.widget.EditText;
32469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
33469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes/**
342cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes * A tint aware {@link android.widget.EditText}.
35fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes * <p>
36fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes * This will automatically be used when you use {@link android.widget.EditText} in your
37fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes * layouts. You should only need to manually use this class when writing custom views.
38469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes */
392cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banespublic class AppCompatEditText extends EditText implements TintableBackgroundView {
40469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
41469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    private static final int[] TINT_ATTRS = {
42469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            android.R.attr.background
43469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    };
44469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
45684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    private TintInfo mInternalBackgroundTint;
46a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    private TintInfo mBackgroundTint;
47684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    private TintManager mTintManager;
48a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes
492cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    public AppCompatEditText(Context context) {
50469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        this(context, null);
51469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    }
52469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
532cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    public AppCompatEditText(Context context, AttributeSet attrs) {
54dd5571652e2ea0eea4af8dbbf10304675d640e1aChris Banes        this(context, attrs, R.attr.editTextStyle);
55469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    }
56469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
572cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    public AppCompatEditText(Context context, AttributeSet attrs, int defStyleAttr) {
58dd5571652e2ea0eea4af8dbbf10304675d640e1aChris Banes        super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
59469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
60fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes        if (TintManager.SHOULD_BE_USED) {
61fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes            TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
62fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes                    TINT_ATTRS, defStyleAttr, 0);
63fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes            if (a.hasValue(0)) {
64351428cd6e15e6d19fe48ce698c994ad3e6f0501Chris Banes                ColorStateList tint = a.getTintManager().getTintList(a.getResourceId(0, -1));
65351428cd6e15e6d19fe48ce698c994ad3e6f0501Chris Banes                if (tint != null) {
66684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes                    setInternalBackgroundTint(tint);
67351428cd6e15e6d19fe48ce698c994ad3e6f0501Chris Banes                }
68fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes            }
69684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            mTintManager = a.getTintManager();
70fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes            a.recycle();
71fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes        }
72469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    }
73a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes
74684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    @Override
75684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    public void setBackgroundResource(int resId) {
76684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        super.setBackgroundResource(resId);
77684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        // Update the default background tint
78684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        setInternalBackgroundTint(mTintManager != null ? mTintManager.getTintList(resId) : null);
79684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    }
80684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes
81684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    @Override
82684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    public void setBackgroundDrawable(Drawable background) {
83684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        super.setBackgroundDrawable(background);
84684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        // We don't know that this drawable is, so we need to clear the default background tint
85684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        setInternalBackgroundTint(null);
86684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    }
87684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes
88a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    /**
89a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * This should be accessed via
90a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * {@link android.support.v4.view.ViewCompat#setBackgroundTintList(android.view.View,
91a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * android.content.res.ColorStateList)}
92a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     *
93a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * @hide
94a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     */
95a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    @Override
96a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
97a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        if (mBackgroundTint == null) {
98a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes            mBackgroundTint = new TintInfo();
99a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        }
100a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        mBackgroundTint.mTintList = tint;
1012cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes        mBackgroundTint.mHasTintList = true;
1022cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes
103a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        applySupportBackgroundTint();
104a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    }
105a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes
106a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    /**
107a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * This should be accessed via
108a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * {@link android.support.v4.view.ViewCompat#getBackgroundTintList(android.view.View)}
109a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     *
110a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * @hide
111a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     */
112a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    @Override
113a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    @Nullable
114a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    public ColorStateList getSupportBackgroundTintList() {
115a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        return mBackgroundTint != null ? mBackgroundTint.mTintList : null;
116a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    }
117a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes
118a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    /**
119a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * This should be accessed via
120a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * {@link android.support.v4.view.ViewCompat#setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode)}
121a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     *
122a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * @hide
123a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     */
124a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    @Override
125a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
126a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        if (mBackgroundTint == null) {
127a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes            mBackgroundTint = new TintInfo();
128a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        }
129a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        mBackgroundTint.mTintMode = tintMode;
1302cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes        mBackgroundTint.mHasTintMode = true;
1312cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes
132a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        applySupportBackgroundTint();
133a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    }
134a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes
135a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    /**
136a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * This should be accessed via
137a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * {@link android.support.v4.view.ViewCompat#getBackgroundTintMode(android.view.View)}
138a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     *
139a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     * @hide
140a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes     */
141a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    @Override
142a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    @Nullable
143a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    public PorterDuff.Mode getSupportBackgroundTintMode() {
144a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        return mBackgroundTint != null ? mBackgroundTint.mTintMode : null;
145a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    }
146a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes
147a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    @Override
148a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    protected void drawableStateChanged() {
149a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        super.drawableStateChanged();
150a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        applySupportBackgroundTint();
151a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    }
152a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes
153a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    private void applySupportBackgroundTint() {
154684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        if (getBackground() != null) {
155684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            if (mBackgroundTint != null) {
156684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes                TintManager.tintViewBackground(this, mBackgroundTint);
157684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            } else if (mInternalBackgroundTint != null) {
158684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes                TintManager.tintViewBackground(this, mInternalBackgroundTint);
159684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            }
160684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        }
161684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    }
162684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes
163684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes    private void setInternalBackgroundTint(ColorStateList tint) {
164684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        if (tint != null) {
165684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            if (mInternalBackgroundTint == null) {
166684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes                mInternalBackgroundTint = new TintInfo();
167684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            }
168684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            mInternalBackgroundTint.mTintList = tint;
169684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            mInternalBackgroundTint.mHasTintList = true;
170684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        } else {
171684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes            mInternalBackgroundTint = null;
172a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes        }
173684dbfaf7105761b5a19a82e8273ed79d3b0641eChris Banes        applySupportBackgroundTint();
174a5f106fbd09335ae504c39b1ee1e0caa3f1238e3Chris Banes    }
175469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes}
176