在ListView中突出显示的搜索结果搜索结果、突出、ListView

2023-09-06 00:25:33 作者:笑咖

我有一个的ListView 字符串秒。随着低于code,我可以突出显示搜索结果,但用户必须键入要搜索的词区分大小写。 我如何实现一个无 - ?情况下的搜索结果,例如像原生的Andr​​oid联系人搜索敏感的语法高亮

下面是我的code为突出。我延长 ArrayAdapter 和实施定制过滤器,以获取字符串进行搜索。在 getView 方法检查我的字符串 ListView中包含 prefixString 并突出显示。

 公共类HighlightListAdapter扩展ArrayAdapter {
    ArrayList的<字符串>对象;
    最终目标MLOCK =新的对象();
    私人的ArrayList<字符串> mOriginalValues​​;
    私人ArrayFilter过滤器;
    私人字符串prefixString;
    公共AuthorsListAdapter(上下文的背景下,INT textViewResourceId,ArrayList的<字符串>对象){
        超(背景下,textViewResourceId,对象);
        this.objects =物体;
    }



    类ViewHolder {
        TextView的作者;

    }

    公共查看getView(最终诠释的立场,观点convertView,ViewGroup中父){

        //指定我们正在转换到一个局部变量视图
        视图V = convertView;
        ViewHolder支架=无效;

        //首先检查是否视图为空。如果是这样,我们要它充气。
        //夸大它的基本含义来呈现,或秀,景色。
        LayoutInflater充气=(LayoutInflater)的getContext()getSystemService(Context.LAYOUT_INFLATER_SERVICE)。
        如果(V == NULL){
            持有人=新ViewHolder();
            V = inflater.inflate(R.layout.author_list_item,NULL);
            holder.author =(TextView中)v.findViewById(R.id.author_list_item_text);
            v.setTag(保持器);

        }其他{
            支架=(ViewHolder)v.getTag();

        }


         最后弦乐笔者= objects.get(位置);
        如果(作家!= NULL){


        holder.author.setText(作者);
        如果(prefixString =空&安培;!&安培; prefixString.length()→1){
            字符串s =作者;



        **如果(s.contains(prefixString)){
            字符串代表= s.replace(prefixString,< B><字体颜色=#2825A6>+ prefixString +< / FONT>< / B>中);
            holder.author.setText(Html.fromHtml(REP));
        } ** // higlight



        }

            }

        返回伏;
    }
    @覆盖
    公众诠释getCount将(){
        // TODO自动生成方法存根
        返回objects.size();
    }



     @覆盖
    公共过滤用getFilter(){
        // TODO自动生成方法存根
        如果(过滤== NULL){
            过滤器=新ArrayFilter();
        }
        返回过滤器;
    }



    @覆盖
    公共对象的getItem(INT位置){
        // TODO自动生成方法存根
        返回this.objects.get(位置);
    }



    私有类ArrayFilter扩展过滤器{
            @覆盖
            保护FilterResults performFiltering(CharSequence的preFIX){
                FilterResults结果=新FilterResults();

                如果(mOriginalValues​​ == NULL){
                    同步(MLOCK){
                        mOriginalValues​​ =新的ArrayList<字符串>(对象);
                    }
                }

                如果(preFIX == NULL || prefix.length()== 0){
                    ArrayList的<字符串>清单;
                    同步(MLOCK){
                        名单=新的ArrayList<字符串>(mOriginalValues​​);
                    }
                    results.values​​ =清单;
                    results.count =则为list.size();
                } 其他 {
                    ** prefixString = prefix.toString(); // **弄的字符串搜索

                    ArrayList的<字符串>值;
                    同步(MLOCK){
                        值=新的ArrayList<字符串>(mOriginalValues​​);
                    }

                    最终诠释计数= values​​.size();
                    最后的ArrayList<字符串> newValues​​ =新的ArrayList<字符串>();

                    的for(int i = 0; I<计数;我++){
                        最终的字符串值= values​​.get(我);
                        最后弦乐valueText = value.toString()与toLowerCase()。

                        //首先对整场比赛,非分裂值
                        如果(valueText.startsWith(prefixString)){
                            newValues​​.add(值);
                        } 其他 {
                            最终的String []字= valueText.split();
                            最后的wordCount INT = words.length;

                            //开始在索引0,如果valueText开始与空间(S)
                            对于(INT K = 0; K<的wordCount; k ++){
                                如果(字[K] .startsWith(prefixString)){
                                    newValues​​.add(值);
                                    打破;
                                }
                            }
                        }
                    }

                    results.values​​ = newValues​​;
                    results.count = newValues​​.size();
                }

                返回结果;
            }
            @燮pressWarnings(未登记)
            @覆盖
            保护无效publishResults(CharSequence的约束,FilterResults结果){
                   对象=(ArrayList的<字符串>)results.values​​;
                如果(results.count大于0){
                                   notifyDataSetChanged();
                               } 其他 {
                                 notifyDataSetInvalidated();
                              }

            }

        };
    }
 

解决方案 Word2010文档中突出显示查找到的内容

本我用的:

在每一次出现被替换(不仅是preFIX) 案例和重音被忽略,而搜索,但保留在结果中。 在这直接使用 SpannableString ,您可以在的setText使用()。我相信这是比使用一个中间步骤HTML更有效。

 公共静态CharSequence的亮点(字符串搜索,字符串originalText){
    //忽略大小写和重音
    //同样的事情应该已经做了搜索文本
    串normalizedText = Normalizer.normalize(originalText,Normalizer.Form.NFD).replaceAll(\\ p {InCombiningDiacriticalMarks} +,).toLowerCase();

    INT开始= normalizedText.indexOf(搜索);
    如果(开始℃,){
        //没有发现,没有向
        返回originalText;
    } 其他 {
        //突出原文每次出现
        //在标准化文本搜索,而
        Spannable强调=新SpannableString(originalText);
        同时(开始> = 0){
            INT spanStart = Math.min(启动,originalText.length());
            INT spanEnd = Math.min(开始+ search.length(),originalText.length());

            highlighted.setSpan(新BackgroundColorSpan(小于background_color&1+),spanStart,spanEnd,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            启动= normalizedText.indexOf(搜索,spanEnd);
        }

        返回突出;
    }
}
 

I have a ListView with Strings. With the below code I can highlight search results, but the user must type the words to search case sensitive. How can I implement a none - case sensitive highlighting of search results for example like the native Android Contact search?

Here is my code for Highlighting. I extend the ArrayAdapter and implement customized filter to get the string to search. In the getView method I check if my String in ListView contains the prefixString and highlight it.

public class HighlightListAdapter extends ArrayAdapter {
    ArrayList<String> objects;
    final Object mLock =new Object();
    private ArrayList<String> mOriginalValues;
    private ArrayFilter filter;
    private String prefixString;
    public AuthorsListAdapter(Context context, int textViewResourceId,  ArrayList<String> objects) {
        super(context, textViewResourceId, objects);
        this.objects = objects;
    }



    class ViewHolder{
        TextView author;

    }

    public View getView(final int position, View convertView, ViewGroup parent){

        // assign the view we are converting to a local variable
        View v = convertView;
        ViewHolder holder = null;

        // first check to see if the view is null. if so, we have to inflate it.
        // to inflate it basically means to render, or show, the view.
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (v == null) {
            holder = new ViewHolder();
            v = inflater.inflate(R.layout.author_list_item, null);
            holder.author =(TextView) v.findViewById(R.id.author_list_item_text);
            v.setTag(holder);

        }else{
            holder = (ViewHolder) v.getTag();

        }


         final String author = objects.get(position);        
        if (author != null) {


        holder.author.setText(author);
        if(prefixString !=null && prefixString.length()>1){
            String s =  author;



        **if(s.contains(prefixString)){
            String rep = s.replace(prefixString,    "<b><font color=#2825A6>"+ prefixString+ "</font></b>");
            holder.author.setText(Html.fromHtml(rep));
        }** // higlight 



        }

            }

        return v;
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return objects.size();
    }



     @Override
    public Filter getFilter() {
        // TODO Auto-generated method stub
        if(filter == null){
            filter =new ArrayFilter();
        }
        return filter;
    }



    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return this.objects.get(position);
    }



    private class ArrayFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence prefix) {
                FilterResults results = new FilterResults();

                if (mOriginalValues == null) {
                    synchronized (mLock) {
                        mOriginalValues = new ArrayList<String>(objects);
                    }
                }

                if (prefix == null || prefix.length() == 0) {
                    ArrayList<String> list;
                    synchronized (mLock) {
                        list = new ArrayList<String>(mOriginalValues);
                    }
                    results.values = list;
                    results.count = list.size();
                } else {
                    **prefixString = prefix.toString();** // get string to search

                    ArrayList<String> values;
                    synchronized (mLock) {
                        values = new ArrayList<String>(mOriginalValues);
                    }

                    final int count = values.size();
                    final ArrayList<String> newValues = new ArrayList<String>();

                    for (int i = 0; i < count; i++) {
                        final String value = values.get(i);
                        final String valueText = value.toString().toLowerCase();

                        // First match against the whole, non-splitted value
                        if (valueText.startsWith(prefixString)) {
                            newValues.add(value);
                        } else {
                            final String[] words = valueText.split(" ");
                            final int wordCount = words.length;

                            // Start at index 0, in case valueText starts with space(s)
                            for (int k = 0; k < wordCount; k++) {
                                if (words[k].startsWith(prefixString)) {
                                    newValues.add(value);
                                    break;
                                }
                            }
                        }
                    }

                    results.values = newValues;
                    results.count = newValues.size();
                }

                return results;
            }
            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint,  FilterResults results) {
                   objects = (ArrayList<String>) results.values;
                if (results.count > 0) {
                                   notifyDataSetChanged();
                               } else {
                                 notifyDataSetInvalidated();
                              }

            }

        };
    }

解决方案

This what I use :

Every occurence is replaced (not only prefix) Case and accent are ignored while searching but retained in the result. It uses directly SpannableString, which you can use in setText(). I believe it's more efficient than using an intermediate html step.

.

public static CharSequence highlight(String search, String originalText) {
    // ignore case and accents
    // the same thing should have been done for the search text
    String normalizedText = Normalizer.normalize(originalText, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "").toLowerCase();

    int start = normalizedText.indexOf(search);
    if (start < 0) {
        // not found, nothing to to
        return originalText;
    } else {
        // highlight each appearance in the original text
        // while searching in normalized text
        Spannable highlighted = new SpannableString(originalText);
        while (start >= 0) {
            int spanStart = Math.min(start, originalText.length());
            int spanEnd = Math.min(start + search.length(), originalText.length());

            highlighted.setSpan(new BackgroundColorSpan(<background_color>), spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            start = normalizedText.indexOf(search, spanEnd);
        }

        return highlighted;
    }
}

 
精彩推荐
图片推荐