如何禁用在Android EditText中输入的表情符号?

时间:2014-04-10 14:23:54

标签: android keyboard emoji

EditText和TextView的text inputType(URI,密码等除外)的大多数实现都允许表情符号 - 尽管在大多数Google键盘配置中,此按钮都是隐藏的。有没有办法禁止在EditText中输入表情符号?是否有一个inputType参数可以与textMultiLine配对以禁用表情符号?

13 个答案:

答案 0 :(得分:24)

修改 build.gradle 文件,将XEditText添加到您的项目中:

dependencies{
    compile 'com.xw.repo:xedittext:2.0.0@aar'
}

之后,在 layout.xml

<com.xw.repo.XEditText
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:x_disableEmoji="true"/>

或者:

自定义EditText,如下所示:

public class CustomEditText extends EditText {
    public CustomEditText(Context context) {
        super(context);
        init();
    }

    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setFilters(new InputFilter[]{new EmojiExcludeFilter()});
    }

    private class EmojiExcludeFilter implements InputFilter {

        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            for (int i = start; i < end; i++) {
                int type = Character.getType(source.charAt(i));
                if (type == Character.SURROGATE || type == Character.OTHER_SYMBOL) {
                    return "";
                }
            }
            return null;
        }
    }
}

两者都能很好用!

答案 1 :(得分:17)

从键盘禁用表情符号有一些棘手的方法..

你只需要设置

<强> android:inputType="textEmailAddress"

for EditText ..

  <EditText
    android:id="@+id/edt_note"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/note"
    android:inputType="textEmailAddress"
    android:padding="10dp"
    android:textColor="@color/white" />

我不确定它会在所有情况下都有效但在我的情况下它对我有用......

答案 2 :(得分:13)

EditText的xml文件中有值digits。你可以设置所有可接受的字符。

<EditText
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:digits="qwertyuiopasdfghjklzxcvbnm 1234567890 QWERTYUIOPASDFGHJKLZXCVBNM" />

我知道,这不是最好的解决方案,但有效:)

答案 3 :(得分:6)

您可以为黑名单/白名单字符编写输入过滤器

public static InputFilter getEditTextFilterEmoji()
{
    return new InputFilter()
    {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
        {
            CharSequence sourceOriginal = source;
            source = replaceEmoji(source);
            end = source.toString().length();

            if (end == 0) return ""; //Return empty string if the input character is already removed

            if (! sourceOriginal.toString().equals(source.toString()))
            {
                char[] v = new char[end - start];
                TextUtils.getChars(source, start, end, v, 0);

                String s = new String(v);

                if (source instanceof Spanned)
                {
                    SpannableString sp = new SpannableString(s);
                    TextUtils.copySpansFrom((Spanned) source, start, end, null, sp, 0);
                    return sp;
                }
                else
                {
                    return s;
                }
            }
            else
            {
                return null; // keep original
            }
        }

        private String replaceEmoji(CharSequence source)
        {

            String notAllowedCharactersRegex = "[^a-zA-Z0-9@#\\$%\\&\\-\\+\\(\\)\\*;:!\\?\\~`£\\{\\}\\[\\]=\\.,_/\\\\\\s'\\\"<>\\^\\|÷×]";
            return source.toString()
                    .replaceAll(notAllowedCharactersRegex, "");
        }

    };
}

然后将其设置为EditText过滤器;

InputFilter[] filterArray = new InputFilter[] {getEditTextFilterEmoji()}
editText.setFilters(filterArray);

答案 4 :(得分:6)

来自@woxingxiao的代码效果很好,直到你在xml中指定任何inputType,例如android:inputType="textMultiLine"

我改变了他的建议,我觉得它很有效。

public class EmojiExcludeEditText extends EditText {

    private EmojiExcludeFilter emojiExcludeFilter;

    public EmojiExcludeEditText(Context context) {
        super(context);
        init();
    }

    public EmojiExcludeEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public EmojiExcludeEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        if (emojiExcludeFilter == null) {
            emojiExcludeFilter = new EmojiExcludeFilter();
        }
        setFilters(new InputFilter[]{emojiExcludeFilter});
    }

    @Override
    public void setFilters(InputFilter[] filters) {
        if (filters.length != 0) { //if length == 0 it will here return when init() is called
            boolean add = true;
            for (InputFilter inputFilter : filters) {
                if (inputFilter == emojiExcludeFilter) {
                    add = false;
                    break;
                }
            }
            if (add) {
                filters = Arrays.copyOf(filters, filters.length + 1);
                filters[filters.length - 1] = emojiExcludeFilter;
            }
        }
        super.setFilters(filters);
    }

    private class EmojiExcludeFilter implements InputFilter {

        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            for (int i = start; i < end; i++) {
                int type = Character.getType(source.charAt(i));
                if (type == Character.SURROGATE || type == Character.OTHER_SYMBOL) {
                    return "";
                }
            }
            return null;
        }
    }
}

答案 5 :(得分:4)

没有什么可以100%禁用表情符号。键盘可以以任何它认为最好的方式操作它所看到的任何模式,因此没有可以阻止表情符号的设置。如果必须阻止它,请使用TextWatcher将字符列入白名单或黑名单。

答案 6 :(得分:1)

添加此表情符号过滤器类:

public class EmojiFilter {
    public static InputFilter[] getFilter()
    {
         InputFilter EMOJI_FILTER = new InputFilter() {

            @Override
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                for (int index = start; index < end; index++) {

                    int type = Character.getType(source.charAt(index));

                    if (type == Character.SURROGATE || type==Character.NON_SPACING_MARK
                            || type==Character.OTHER_SYMBOL) {
                        return "";
                    }
                }
                return null;
            }
        };
         return new InputFilter[]{EMOJI_FILTER};
    }
}

要在编辑文本中禁用表情符号,请执行以下操作:

etParkingInstruction.setFilters(EmojiFilter.getFilter());

有些表情符号可以输入,所以我添加了:

type==Character.NON_SPACING_MARK || type==Character.OTHER_SYMBOL

在if条件下。

答案 7 :(得分:1)

表情符号使用 Unicode 区域,代码点范围从 U+1F604 到 U+1F539。 并且 Character.SURROGATE 保留了范围超过 Emoji 的范围。

val EMOJI_FILTER =InputFilter { source, start, end, dest, dstart, dend ->
                for (index in start until end) {
                    val type = Character.getType(source[index])
                    if (type == Character.SURROGATE.toInt()) {
                        return@InputFilter ""
                    }
                }
                null
            }


        etLintEdt.filters = arrayOf(EMOJI_FILTER)

答案 8 :(得分:0)

您可以使用输入过滤器删除不需要的字符,这里我使用ascci值进行过滤。

public class CustomEditText extends AppCompatEditText {
private InputFilter unwantedCharacterFilter;

public CustomEditText(Context context) {
    super(context);
}

public CustomEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

private void init() {
    setFilters(new InputFilter[]{});
}
private InputFilter getUnwantedCharacterFilter() {
    if (null == unwantedCharacterFilter) {
        unwantedCharacterFilter = new InputFilter() {
            @Override
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                if (!TextUtils.isEmpty(source)) {
                    for (int index = start; index < end; index++) {
                        if (source.charAt(index) < 0 || source.charAt(index) > 177) {
                            return "";
                        }
                    }
                }
                return null;
            }
        };
    }
    return unwantedCharacterFilter;
}

@Override
public void setFilters(InputFilter[] filters) {
    List<InputFilter> filterList = new ArrayList<>(Arrays.asList(filters));
    filterList.add(getUnwantedCharacterFilter());
    InputFilter specifiedFilters[] = filterList.toArray(new InputFilter[]{});
    super.setFilters(specifiedFilters);
}

}

答案 9 :(得分:0)

您可以将输入类型用作“textVisiblePassword”。这将禁用键盘上的表情符号。但是用户仍然可以将表情符号复制粘贴到编辑文本中。

<EditText
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:inputType="textVisiblePassword" />

答案 10 :(得分:0)

我为此制作了 Kotlin 扩展。它还可以防止 Emoji 的复制粘贴。

扩展:

fun EditText.filterEmoji() {
    filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
        source.filter { Character.getType(it) != Character.SURROGATE.toInt() }
    })
}

在 Kotlin 类中:

editText.filterEmoji()

就是这样。享受!

答案 11 :(得分:-1)

另一种解决方案:

mEtMessageText.setInputType( InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS | InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);

在此示例中,它显示了ENTER按钮

InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS 等同于XML布局中的android:inputType =“ textEmailAddress

答案 12 :(得分:-3)

尝试android:inputtype="textUri|textMultiLine"

在此参数中,键盘会将语音输入按钮更改为“/”按钮。