EmojiTextViewHelper.java revision 6e120d58ca0644c25fedee1d7e1d24b9547f43a8
1/*
2 * Copyright (C) 2017 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 */
16package android.support.text.emoji.widget;
17
18import android.support.annotation.NonNull;
19import android.support.v4.util.Preconditions;
20import android.text.InputFilter;
21import android.text.method.PasswordTransformationMethod;
22import android.text.method.TransformationMethod;
23import android.widget.TextView;
24
25/**
26 * Utility class to enhance a TextView with emoji capability.
27 */
28public final class EmojiTextViewHelper {
29    private final TextView mTextView;
30    private final EmojiInputFilter mEmojiInputFilter;
31
32    /**
33     * Default constructor.
34     *
35     * @param textView TextView instance
36     */
37    public EmojiTextViewHelper(@NonNull TextView textView) {
38        Preconditions.checkNotNull(textView, "textView cannot be null");
39        mTextView = textView;
40        mEmojiInputFilter = new EmojiInputFilter(textView);
41    }
42
43    /**
44     * Updates widget's TransformationMethod so that the transformed text can be processed.
45     * Should be called in the widget constructor.
46     *
47     * @see #getTransformationMethod(TransformationMethod)
48     */
49    public void updateTransformationMethod() {
50        final TransformationMethod transformationMethod = mTextView.getTransformationMethod();
51        if (transformationMethod != null
52                && !(transformationMethod instanceof PasswordTransformationMethod)) {
53            mTextView.setTransformationMethod(getTransformationMethod(transformationMethod));
54        }
55    }
56
57    /**
58     * Appends EmojiCompat InputFilters to the widget InputFilters. Should be called by {@link
59     * TextView#setFilters(InputFilter[])} to update the InputFilters.
60     * <p/>
61     * <pre><code> {@literal @}Override
62     * public void setFilters(InputFilter[] filters) {
63     *     super.setFilters(getEmojiTextViewHelper().getFilters(filters));
64     * }</code></pre>
65     *
66     * @param filters InputFilter array passed to {@link TextView#setFilters(InputFilter[])}
67     *
68     * @return same copy if the array already contains EmojiCompat InputFilter. A new array copy if
69     * not.
70     */
71    public InputFilter[] getFilters(@NonNull final InputFilter[] filters) {
72        final int count = filters.length;
73        for (int i = 0; i < count; i++) {
74            if (filters[i] instanceof EmojiInputFilter) {
75                return filters;
76            }
77        }
78        final InputFilter[] newFilters = new InputFilter[filters.length + 1];
79        System.arraycopy(filters, 0, newFilters, 0, count);
80        newFilters[count] = mEmojiInputFilter;
81        return newFilters;
82    }
83
84    /**
85     * Returns transformation method that can update the transformed text to display emojis.
86     *
87     * @param transformationMethod instance to be wrapped
88     */
89    public TransformationMethod getTransformationMethod(
90            final TransformationMethod transformationMethod) {
91        return new EmojiTransformationMethod(transformationMethod);
92    }
93
94    /**
95     * Call when allCaps is set on TextView.
96     * <p/>
97     * <pre><code> {@literal @}Override
98     * public void setAllCaps(boolean allCaps) {
99     *     super.setAllCaps(allCaps);
100     *     getEmojiTextViewHelper().setAllCaps(allCaps);
101     * }</code></pre>
102     *
103     * @param allCaps allCaps parameter passed to {@link TextView#setAllCaps(boolean)}
104     */
105    public void setAllCaps(boolean allCaps) {
106        // When allCaps is set to false TextView sets the transformation method to be null. We
107        // are only interested when allCaps is set to true in order to wrap the original method.
108        if (allCaps) {
109            updateTransformationMethod();
110        }
111    }
112}
113