Android-->轻松打造带删除按钮的输入框(EditText),附Emoji表情过滤

输入框带删除按钮, 此乃标配, 实现起来方法也很多, 网上开源也很多.

但是, 没事就喜欢瞎折腾.

上图说话.

只是在原生的基础上加了扩展. 相对来说入侵非常少, 使用方法和原生的一模一样.无任何阉割.



完整代码:

public class ExEditText extends AppCompatEditText {

    Rect clearRect = new Rect();

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

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

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

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        //在不影响默认过滤规则的情况下,添加Emoji表情过滤
        if ("emoji".equalsIgnoreCase(String.valueOf(getTag()))) {
            final InputFilter[] filters = getFilters();
            final InputFilter[] newFilters = new InputFilter[filters.length + 1];
            System.arraycopy(filters, 0, newFilters, 0, filters.length);
            newFilters[filters.length] = new EmojiFilter();
            setFilters(newFilters);
        }
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        //焦点改变,检查是否需要显示删除按钮
        checkEdit(focused);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //用来计算删除按钮所在的矩形区域
        clearRect.set(w - getPaddingRight() - Math.min(w, h), getPaddingTop(), w - getPaddingRight(), Math.min(w, h) - getPaddingBottom());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //检查点击删除按钮区域,并且当前具有焦点
        if (event.getAction() == MotionEvent.ACTION_DOWN && isFocused()) {
            //检查是否在删除按钮矩形区域,按下
            if (checkClear(event.getX(), event.getY())) {
                //如果当前已经是空的, 不处理Touch事件,否则清空文本,达到删除的效果
                if (!TextUtils.isEmpty(getText())) {
                    setText("");
                    return true;
                }
            }
        }
        return super.onTouchEvent(event);
    }

    private void checkEdit(boolean focused) {
        if (TextUtils.isEmpty(getText()) || !focused) {
            setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
        } else {
            //这里才是关键, 用的是原生的方法显示删除图标.
            setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.base_edit_delete, 0);
        }
    }

    //坐标是否在按钮区
    private boolean checkClear(float x, float y) {
        return clearRect.contains(((int) x), (int) y);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        //时刻检查一下
        checkEdit(true);
    }
}


Emoji表情过滤:

可能还是有些特殊的Emoji表情,或者字符表情无法过滤, 抱歉;

如果你发现, 请告知, 让我们一起完善一下, 谢谢!

public class EmojiFilter implements InputFilter {
    Pattern emojiPattern = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
            Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
    private int mMax = -1;//默认不过滤长度

    public EmojiFilter() {
    }

    public EmojiFilter(int max) {
        mMax = max;
    }

    /**
     * 检测是否有emoji表情
     *
     * @param source
     * @return
     */
    public static boolean containsEmoji(CharSequence source) {
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (!isEmojiCharacter(codePoint)) { //如果不能匹配,则该字符是Emoji表情
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否是Emoji
     *
     * @param codePoint 比较的单个字符
     * @return
     */
    private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) ||
                (codePoint == 0xD) || ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || ((codePoint >= 0x10000)
                && (codePoint <= 0x10FFFF));
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
                               int dend) {
        if (this.emojiPattern.matcher(source).find() || containsEmoji(source)) {
            return "";
        }

        if (mMax != -1) {
            int keep = mMax - (dest.length() - (dend - dstart));
            if (keep <= 0) {
                return "";
            } else if (keep >= end - start) {
                return null; // keep original
            } else {
                keep += start;
                if (Character.isHighSurrogate(source.charAt(keep - 1))) {
                    --keep;
                    if (keep == start) {
                        return "";
                    }
                }
                return source.subSequence(start, keep);
            }
        }

        return source;
    }
}


至此: 文章就结束了,如有疑问: QQ群 Android:274306954 Swift:399799363 欢迎您的加入.

时间: 2024-10-17 07:33:08

Android-->轻松打造带删除按钮的输入框(EditText),附Emoji表情过滤的相关文章

【Android】android 输入框EditText禁止输入Emoji表情符

转载地址:http://blog.csdn.net/elsdnwn/article/details/45390771 package com.liujy.ui.wiget;import android.content.Context;import android.text.Editable;import android.text.Selection;import android.text.Spannable;import android.text.TextWatcher;import andro

35.Android之带删除按钮EditText学习

今天实现Android里自定义带删除功能的EditText,效果如下: 当输入内容时,EditText变为带有一个删除功能按钮的编辑框,如图: 实现代码很简单,直接上代码, 布局文件xml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 an

自定义EditText 实现带清空按钮的输入框

注:本文转载自csdn,其中实现清除功能所采用的方案比较可取. 原文如下: 项目要求:做出包含根据情况可变色的下划线,左侧有可变图标,右侧有可变删除标志的edittext,如图 记录制作过程: 第一版本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

[Android]自己定义带删除输入框

在项目开发中,带删除button输入框也是人们经常常使用到的,该文章便介绍一下怎样创建一个带删除输入框.当中,须要解决的问题例如以下: a)创建自己定义editText类 b)在自己定义editText中显示删除图片 c)依据输入框的输入情况显示或隐藏图片 d)点击删除图片文字消失,图片隐藏 e)依据输入框焦点失去和获得状态显示或隐藏图片 好了.问题明白了.開始实现功能: a)创建一个名为MyClearEditText的class文件,并集成EditText,实现其构造方法: public My

Android学习小Demo(22)带删除按钮的TextView

很多时候,会有一些很简单的需求,比如你利用一个Button弹出某个页面,选择了某个对象之后,你会将对象的某些属性,比如名称之类,显示在按钮上. 而紧跟着,又会想着,能不能把刚选择的对象给清掉,比如把按钮上的文字给去掉,这个时候,你就会希望,要是按钮后面还能够有多一个图标,一点击,就把当前控件的文字等清除掉就好了,并且还会对应的回调函数,让我们多处理一些事情,那多好. 很可惜,Android并没有提供现成的控件供我们这样使用,但换个角度想想,这又根本不可惜,因为我们可以自己来实现这样的效果呀,这是

安卓自定义带删除图标的输入框EditView

在安卓中我们使用默认的Editview是只能输入文字的,但是想要删除,我们得利用输入法的删除按钮来一个个删除,现在在好多应用当中,会在输入框的最后出现一个删除图片,点击就清空了所有的数据,这个很方便.下面我们来实现一下. 先看下效果图: 我们这里实现的是,当输入框有文本是,才会出现这个删除图标.当输入为空是,就会消失,其实就是自定义一个Ediiview: /** * 输入文本框 右边有自带的删除按钮 当有输入时,显示删除按钮,当无输入时,不显示删除按钮. * * */ public class

带删除按钮的EditText

在使用输入框的时候,常常需要在输入框后带有一键清除输入内容的按钮.采用自定义View的方式是复用性较高的方法.另一方面也可以采用控件"控件+监听"的较为简单的方法来实现. 布局文件: <LinearLayout     android:layout_width="match_parent"     android:layout_height="0dp"     android:layout_weight="1">

Android基础入门教程——3.5 监听EditText的内容变化

Android基础入门教程--3.5 监听EditText的内容变化 标签(空格分隔): Android基础入门教程 本节引言: 在前面我们已经学过EditText控件了,本节来说下如何监听输入框的内容变化! 这个再实际开发中非常实用,另外,附带着说下如何实现EditText的密码可见 与不可见!好了,开始本节内容! 1.监听EditText的内容变化 由题可知,是基于监听的事件处理机制,好像前面的点击事件是OnClickListener,文本内容 变化的监听器则是:TextWatcher,我们

Android 自定义EditText输入框 带清空按钮

总结  Android 自定义EditText输入框 带清空按钮 当用户输入字符后  EditText会自动在输入框的内部右侧出现删除按钮 重写EditText达到简化布局的效果 效果图: 继承EditText package com.example.myedittexttest; import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.Drawable; imp