1/*
2 * Copyright (C) 2015 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
17package android.support.v7.widget;
18
19import android.content.Context;
20import android.content.res.ColorStateList;
21import android.graphics.PorterDuff;
22import android.graphics.drawable.Drawable;
23import android.support.annotation.DrawableRes;
24import android.support.annotation.Nullable;
25import android.support.v4.view.TintableBackgroundView;
26import android.support.v7.appcompat.R;
27import android.util.AttributeSet;
28import android.widget.TextView;
29
30/**
31 * A {@link TextView} which supports compatible features on older version of the platform,
32 * including:
33 * <ul>
34 *     <li>Supports {@link R.attr#textAllCaps} style attribute which works back to
35 *     {@link android.os.Build.VERSION_CODES#ECLAIR_MR1 Eclair MR1}.</li>
36 *     <li>Allows dynamic tint of it background via the background tint methods in
37 *     {@link android.support.v4.view.ViewCompat}.</li>
38 *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
39 *     {@link R.attr#backgroundTintMode}.</li>
40 * </ul>
41 *
42 * <p>This will automatically be used when you use {@link TextView} in your layouts.
43 * You should only need to manually use this class when writing custom views.</p>
44 */
45public class AppCompatTextView extends TextView implements TintableBackgroundView {
46
47    private AppCompatDrawableManager mDrawableManager;
48    private AppCompatBackgroundHelper mBackgroundTintHelper;
49    private AppCompatTextHelper mTextHelper;
50
51    public AppCompatTextView(Context context) {
52        this(context, null);
53    }
54
55    public AppCompatTextView(Context context, AttributeSet attrs) {
56        this(context, attrs, android.R.attr.textViewStyle);
57    }
58
59    public AppCompatTextView(Context context, AttributeSet attrs, int defStyleAttr) {
60        super(TintContextWrapper.wrap(context), attrs, defStyleAttr);
61
62        mDrawableManager = AppCompatDrawableManager.get();
63        mBackgroundTintHelper = new AppCompatBackgroundHelper(this, mDrawableManager);
64        mBackgroundTintHelper.loadFromAttributes(attrs, defStyleAttr);
65
66        mTextHelper = AppCompatTextHelper.create(this);
67        mTextHelper.loadFromAttributes(attrs, defStyleAttr);
68        mTextHelper.applyCompoundDrawablesTints();
69    }
70
71    @Override
72    public void setBackgroundResource(@DrawableRes int resId) {
73        super.setBackgroundResource(resId);
74        if (mBackgroundTintHelper != null) {
75            mBackgroundTintHelper.onSetBackgroundResource(resId);
76        }
77    }
78
79    @Override
80    public void setBackgroundDrawable(Drawable background) {
81        super.setBackgroundDrawable(background);
82        if (mBackgroundTintHelper != null) {
83            mBackgroundTintHelper.onSetBackgroundDrawable(background);
84        }
85    }
86
87    /**
88     * This should be accessed via
89     * {@link android.support.v4.view.ViewCompat#setBackgroundTintList(android.view.View, ColorStateList)}
90     *
91     * @hide
92     */
93    @Override
94    public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
95        if (mBackgroundTintHelper != null) {
96            mBackgroundTintHelper.setSupportBackgroundTintList(tint);
97        }
98    }
99
100    /**
101     * This should be accessed via
102     * {@link android.support.v4.view.ViewCompat#getBackgroundTintList(android.view.View)}
103     *
104     * @hide
105     */
106    @Override
107    @Nullable
108    public ColorStateList getSupportBackgroundTintList() {
109        return mBackgroundTintHelper != null
110                ? mBackgroundTintHelper.getSupportBackgroundTintList() : null;
111    }
112
113    /**
114     * This should be accessed via
115     * {@link android.support.v4.view.ViewCompat#setBackgroundTintMode(android.view.View, PorterDuff.Mode)}
116     *
117     * @hide
118     */
119    @Override
120    public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
121        if (mBackgroundTintHelper != null) {
122            mBackgroundTintHelper.setSupportBackgroundTintMode(tintMode);
123        }
124    }
125
126    /**
127     * This should be accessed via
128     * {@link android.support.v4.view.ViewCompat#getBackgroundTintMode(android.view.View)}
129     *
130     * @hide
131     */
132    @Override
133    @Nullable
134    public PorterDuff.Mode getSupportBackgroundTintMode() {
135        return mBackgroundTintHelper != null
136                ? mBackgroundTintHelper.getSupportBackgroundTintMode() : null;
137    }
138
139    @Override
140    public void setTextAppearance(Context context, int resId) {
141        super.setTextAppearance(context, resId);
142        if (mTextHelper != null) {
143            mTextHelper.onSetTextAppearance(context, resId);
144        }
145    }
146
147    @Override
148    protected void drawableStateChanged() {
149        super.drawableStateChanged();
150        if (mBackgroundTintHelper != null) {
151            mBackgroundTintHelper.applySupportBackgroundTint();
152        }
153        if (mTextHelper != null) {
154            mTextHelper.applyCompoundDrawablesTints();
155        }
156    }
157}
158