美文网首页Android 开发
如何在Edittext中实时输入文字,然后根据正则匹配改变颜色

如何在Edittext中实时输入文字,然后根据正则匹配改变颜色

作者: 乱逃 | 来源:发表于2020-02-19 21:07 被阅读0次

    ,当然还有许多逻辑可能需要你在处理处理,这个只能算一个简单版最近在写一个功能,类似于微博的话题,#xx 这种。我们在输入框中输入文字,如果输入了#,那就开始搜索后台服务器。然后给你展示一堆热门的话题 ,你点击,选中,然后高亮显示 或者你自己输入,最后以空格啊特殊符号啊,结束,这个规则可以自己定制。需求来了,先简单分析一波 吧:
    1.正则规则,这个简单,根据你们制定的,我这规则是,#号开头,非汉字或者字母数字结束,最多3个话题
    所以正则是:"(#(#{0}?[\\u4e00-\\u9fa5A-Za-z0-9]+))"
    然后非法限定字符是([\\u4e00-\\u9fa5A-Za-z0-9]+)

    2.判断当前输入的是啥,所以肯定得在TextWatch里做文章
    onTextChanged 中参数的意思,你得先去了解一波,,before=0 是你往里面加字符串,count=0,是删除字符串,然后对应着判断逻辑就好
    3。改变颜色 这里的水有点深,可能是我太菜了。
    第一个版本:参考 https://github.com/limedroid/TagEditText,
    afterTextChanged里的写法,改吧改吧,能用,但是会有问题,在一些机器的一些输入法中,你输入一个,然后给你来个智能提示,你点了那个提示,就出问题了,或者是各种下划线,不能操作,
    然后就是搜啊搜的
    第二个参考:https://www.jianshu.com/p/d0dbb3445cc1

    然后还有第三,第四,大体上都是 在after里,先removewatch,再加watch,或者用html.fromHtml来改颜色,但是都有问题。
    最终版来自于 https://stackoverflow.com/questions/42786493/syntax-highlighting-on-android-edittext-using-span

    就不废话了,,直接上代码吧,当然了这个只能算一个简单版,还有许多逻辑需要你自己处理,我项目中后续也改了不少,这里只是提供个思路,重点是如何在edittext中输入然后实时改颜色或者其他span

                public class TagEditText extends AppCompatEditText {
    
        public String prefixTag = "#";
        private String endTag = "#";
        private String tagRegex = DEF_REGEX;
        public static final String DEF_REGEX = "(#(#{0}?[\\u4e00-\\u9fa5A-Za-z0-9]+))";//字符串中只允许1个#
        public static String ILLEGAL_REGEX = "([\\u4e00-\\u9fa5A-Za-z0-9]+)";
    
        private int tagColor = Color.parseColor("#1B97AA");
    
    
        private boolean isSearch = false;
    
    
        List<String> tagList = new ArrayList<>();
        int lastSelction = 0;
    
    
        public void setSearchState(boolean isSearch) {
            this.isSearch = isSearch;
        }
    
        public TagEditText(Context context) {
            super(context);
            initView();
        }
    
        public TagEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
            initView();
        }
    
        public TagEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initView();
        }
    
    
        private void initView() {
            addTextChangedListener(new TextWatcher() {
                private String mBeafore = "";
                private int deletCount = 0;
                private int deleteStart = 0;
    
                private int selection = 0;
    
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    mBeafore = s.toString();
                    deletCount = count;
                    deleteStart = start;
                    selection=getSelectionEnd();
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    selection=getSelectionEnd();
                    if (before == 0) {
                      //添加
                        if (s.subSequence(start, start + count).toString().equals(prefixTag)) {
                            Timber.d("---开始搜索");
    
                            if (getTagList().size() >= 3) {
    
                                isSearch = false;
                                if (searchListener != null) {
                                    searchListener.unSearch();
                                }
                            } else {
                                isSearch = true;
                                if (searchListener != null) {
                                    searchListener.search("");
                                }
                            }
    
                        } else if (s.subSequence(start, start + count).toString().equals(" ") || s.subSequence(start, start + count).toString().equals("\r\n") || s.subSequence(start, start + count).toString().equals("\n") || !check(s.subSequence(start, start + count).toString())) {
                            //空格搜索结束
                            isSearch = false;
                            if (searchListener != null) {
                                searchListener.unSearch();
                            }
                        } else {
                            if (isSearch) {
                                String str = s.toString().substring(s.toString().lastIndexOf(prefixTag) + 1);
                                Timber.d("---搜索%s", str);
                                if (searchListener != null) {
                                    searchListener.search(str);
                                }
    
                            } else {
                                Timber.d("---不搜索");
                                if (searchListener != null) {
                                    searchListener.unSearch();
                                }
                            }
                        }
                    } else if (count == 0) {
                        Timber.d("----delete");
                        //删除
                        if (getTagList().size() > 3) {
                            isSearch = false;
                            if (searchListener != null) {
                                searchListener.unSearch();
                            }
                            return;
                        }
                        String str = s.toString().substring(s.toString().lastIndexOf(prefixTag) + 1, mBeafore.length() - before);
                        String deleteStr = mBeafore.substring(deleteStart, deleteStart + deletCount);
                        if (isSearch) {
                            if (prefixTag.equals(deleteStr)) {
                                //删除的是#
                                isSearch = false;
                                Timber.d("---不搜索%s", str);
                                if (searchListener != null) {
                                    searchListener.unSearch();
                                }
                            } else {
                                Timber.d("---搜索%s", str);
    
                                if (searchListener != null) {
                                    searchListener.search(str);
                                }
    
                            }
                        } else {
    
                            if (s.toString().lastIndexOf(prefixTag) < 0) {
                                Timber.d("---不搜索%s", str);
    
                                isSearch = false;
                                if (searchListener != null) {
                                    searchListener.unSearch();
                                }
                                return;
                            }
                            String tempStr = s.toString().substring(s.toString().lastIndexOf(prefixTag), mBeafore.length() - before);
                            Timber.d("----tempStr=%s", tempStr);
                            Pattern pattern = Pattern.compile(tagRegex);
                            Matcher matcher = pattern.matcher(tempStr);
                            String match = "";
                            if (matcher.find()) {
                                match = matcher.group(1);
                                if (match.equals(tempStr)) {
                                    Timber.d("---搜索%s", str);
                                    isSearch = true;
                                    if (searchListener != null) {
                                        searchListener.search(str);
                                    }
    
                                }
                            } else if (tempStr.equals(prefixTag)) {
                                Timber.d("---搜索%s", str);
                                isSearch = true;
                                if (searchListener != null) {
                                    searchListener.search(str);
                                }
                            } else {
                                Timber.d("---不搜索%s", str);
    
                                isSearch = false;
                                if (searchListener != null) {
                                    searchListener.unSearch();
                                }
                            }
                        }
                    }
    
    
                }
    
                @Override
                public void afterTextChanged(Editable text) {
                    if (TextUtils.isEmpty(text)) {
                        isSearch = false;
                        searchListener.unSearch();
                        return;
    
                    }
                    removeSpans(text, ForegroundColorSpan.class);
    
                    String textStr = text.toString();
    
                    if (TextUtils.isEmpty(tagRegex)) tagRegex = DEF_REGEX;
    
                    Pattern pattern = Pattern.compile(tagRegex);
                    Matcher matcher = pattern.matcher(textStr);
    
                    tagList.clear();
                    while (matcher.find()) {
                        if (tagList.size() < 3) {
                            tagList.add(matcher.group(1));
                            text.setSpan(new ForegroundColorSpan(tagColor),
                                    matcher.start(),
                                    matcher.end(),
                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
    
                    }
                    if (selection==0){
                        Selection.setSelection(text,text.length());
                    }else {
                        Selection.setSelection(text,selection);
                    }
                }
    
    
            });
        }
    
        void removeSpans(Editable e, Class<? extends CharacterStyle> type) {
            CharacterStyle[] spans = e.getSpans(0, e.length(), type);
            for (CharacterStyle span : spans) {
                e.removeSpan(span);
            }
        }
    
        @Override
        protected void onSelectionChanged(int selStart, int selEnd) {
            super.onSelectionChanged(selStart, selEnd);
    
    
        }
    
        /**
         * 设置tag
         *
         * @param prefixTag
         * @param endTag
         */
        public TagEditText tag(String prefixTag, String endTag) {
            if (TextUtils.isEmpty(prefixTag) || TextUtils.isEmpty(endTag)) return this;
    
            this.prefixTag = prefixTag;
            this.endTag = endTag;
    
            tagRegex = new StringBuilder("(")
                    .append(prefixTag)
                    .append(".+?")
                    .append(endTag)
                    .append(")")
                    .toString();
            return this;
        }
    
        /**
         * 设置标签颜色
         *
         * @param tagColor
         * @return
         */
        public TagEditText tagColor(int tagColor) {
            this.tagColor = tagColor;
            return this;
        }
    
    
        /**
         * 追加文本
         *
         * @param text
         */
        public void appendText(String text) {
            if (TextUtils.isEmpty(text)) return;
    
            SpannableStringBuilder builder = new SpannableStringBuilder(getText());
            builder.append(text);
            setText(builder);
            setSelection(getText().toString().length());
        }
    
    
        /**
         * 删除文本[删除最后匹配]
         *
         * @param text
         */
        public void removeText(String text) {
            if (TextUtils.isEmpty(text)) return;
    
            SpannableStringBuilder builder = new SpannableStringBuilder(getText());
            int pos = text.toString().indexOf(text);
            if (pos > -1) {
                try {
                    builder = builder.delete(pos, pos + text.length());
                    setText(builder);
                } catch (Exception e) {
                }
    
            }
        }
    
        /**
         * 获取标签集合
         *
         * @return
         */
        public List<String> getTagList() {
    
            ArrayList<String> list = new ArrayList<>();
            for (int i = 0; i < tagList.size(); i++) {
                list.add(tagList.get(i).replace(prefixTag, ""));
            }
    
    
            return list;
    //        Pattern pattern = Pattern.compile(tagRegex);
    //        Matcher matcher = pattern.matcher(getText());
    //
    //        Set<String> picSet = new HashSet<>();
    //        ArrayList<String> tagList = new ArrayList<>();
    //
    //        while (matcher.find()) {
    //            picSet.add(matcher.group(1).replace(prefixTag, "").replace(endTag, ""));
    //        }
    //
    //        tagList.clear();
    //        tagList.addAll(picSet);     //去重
    //        return tagList;
        }
    
        public interface OnSearchListener {
            void search(String text);
    
            void unSearch();
    
        }
    
        public OnSearchListener searchListener;
    
        public void setOnSearchListener(OnSearchListener searchListener) {
            this.searchListener = searchListener;
        }
    
        public boolean check(String text) {
            Pattern pattern = Pattern.compile(ILLEGAL_REGEX);
            Matcher matcher = pattern.matcher(text);
            while (matcher.find()) {
    
                return true;
            }
    
            return false;
        }
    
    }
    

    相关文章

      网友评论

        本文标题:如何在Edittext中实时输入文字,然后根据正则匹配改变颜色

        本文链接:https://www.haomeiwen.com/subject/gelzfhtx.html