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 */ 16 17 package androidx.emoji.widget; 18 19 import android.content.Context; 20 import android.text.method.KeyListener; 21 import android.util.AttributeSet; 22 import android.view.inputmethod.EditorInfo; 23 import android.view.inputmethod.InputConnection; 24 25 import androidx.annotation.IntRange; 26 import androidx.appcompat.widget.AppCompatEditText; 27 import androidx.emoji.text.EmojiCompat; 28 29 import org.jspecify.annotations.Nullable; 30 31 /** 32 * AppCompatEditText widget enhanced with emoji capability by using {@link EmojiEditTextHelper}. 33 * When used on devices running API 18 or below, this widget acts as a regular 34 * {@link AppCompatEditText}. 35 * 36 * {@link androidx.emoji.R.attr#maxEmojiCount} 37 */ 38 public class EmojiAppCompatEditText extends AppCompatEditText { 39 private EmojiEditTextHelper mEmojiEditTextHelper; 40 41 /** 42 * Prevent calling {@link #init(AttributeSet, int)} multiple times in case super() constructors 43 * call other constructors. 44 */ 45 private boolean mInitialized; 46 EmojiAppCompatEditText(Context context)47 public EmojiAppCompatEditText(Context context) { 48 super(context); 49 init(null /*attrs*/, 0 /*defStyleAttr*/); 50 } 51 EmojiAppCompatEditText(Context context, AttributeSet attrs)52 public EmojiAppCompatEditText(Context context, AttributeSet attrs) { 53 super(context, attrs); 54 init(attrs, androidx.appcompat.R.attr.editTextStyle); 55 } 56 EmojiAppCompatEditText(Context context, AttributeSet attrs, int defStyleAttr)57 public EmojiAppCompatEditText(Context context, AttributeSet attrs, int defStyleAttr) { 58 super(context, attrs, defStyleAttr); 59 init(attrs, defStyleAttr); 60 } 61 init(@ullable AttributeSet attrs, int defStyleAttr)62 private void init(@Nullable AttributeSet attrs, int defStyleAttr) { 63 if (!mInitialized) { 64 mInitialized = true; 65 final EditTextAttributeHelper attrHelper = new EditTextAttributeHelper(this, attrs, 66 defStyleAttr, 0); 67 setMaxEmojiCount(attrHelper.getMaxEmojiCount()); 68 setKeyListener(super.getKeyListener()); 69 } 70 } 71 72 @Override setKeyListener(@ullable KeyListener keyListener)73 public void setKeyListener(@Nullable KeyListener keyListener) { 74 if (keyListener != null) { 75 keyListener = getEmojiEditTextHelper().getKeyListener(keyListener); 76 } 77 super.setKeyListener(keyListener); 78 } 79 80 @Override onCreateInputConnection(EditorInfo outAttrs)81 public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 82 InputConnection inputConnection = super.onCreateInputConnection(outAttrs); 83 return getEmojiEditTextHelper().onCreateInputConnection(inputConnection, outAttrs); 84 } 85 86 /** 87 * Set the maximum number of EmojiSpans to be added to a CharSequence. The number of spans in a 88 * CharSequence affects the performance of the EditText insert/delete operations. Insert/delete 89 * operations slow down as the number of spans increases. 90 * 91 * @param maxEmojiCount maximum number of EmojiSpans to be added to a single CharSequence, 92 * should be equal or greater than 0 93 * 94 * @see EmojiCompat#process(CharSequence, int, int, int) 95 * 96 * {@link androidx.emoji.R.attr#maxEmojiCount} 97 */ setMaxEmojiCount(@ntRangefrom = 0) int maxEmojiCount)98 public void setMaxEmojiCount(@IntRange(from = 0) int maxEmojiCount) { 99 getEmojiEditTextHelper().setMaxEmojiCount(maxEmojiCount); 100 } 101 102 /** 103 * Returns the maximum number of EmojiSpans to be added to a CharSequence. 104 * 105 * @see #setMaxEmojiCount(int) 106 * @see EmojiCompat#process(CharSequence, int, int, int) 107 * 108 * {@link androidx.emoji.R.attr#maxEmojiCount} 109 */ getMaxEmojiCount()110 public int getMaxEmojiCount() { 111 return getEmojiEditTextHelper().getMaxEmojiCount(); 112 } 113 getEmojiEditTextHelper()114 private EmojiEditTextHelper getEmojiEditTextHelper() { 115 if (mEmojiEditTextHelper == null) { 116 mEmojiEditTextHelper = new EmojiEditTextHelper(this); 117 } 118 return mEmojiEditTextHelper; 119 } 120 } 121