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