在 AutoCompleteTextview 中获取过滤后的数组大小 [英] Get filtered array size in AutoCompleteTextview

查看:25
本文介绍了在 AutoCompleteTextview 中获取过滤后的数组大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究用户可以在其中搜索数据的项目.为此,我已经实现了 AutoCompleteTextView.

I am working on the project in which user can search data. For that, I have implemented AutoCompleteTextView.

 autoComplete.setAdapter(new ArrayAdapter<String>(CheckRiskActivity.this,
                                        R.layout.auto_text_row, druglist));
                                autoComplete.setThreshold(1);
//druglist is my arraylist

文本更改监听器如下:

autoComplete.addTextChangedListener(new TextWatcher() {

        @Override
        public void afterTextChanged(Editable s) {
            // here I want to get the size of filtered array list every time when the user adds any character.
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start,
                                  int before, int count) {
        }
    });

说明:如果我的初始数组大小为 100,并且用户键入a",那么我想获取过滤数组的大小.

Explanation: If my initial array size is 100 and if the user types 'a', then I want to get the size of filtered array.

注意:我已经尝试过 autoComplete.getAdapter().getCount(); 但它在添加一个字符后给出了实际结果.

Note: I have tried autoComplete.getAdapter().getCount(); but it gives the actual result after adding one more character.

推荐答案

您无法在 TextWatcher 中获得正确的过滤项计数,因为过滤通常比 TextWatcher 花费的时间更长事件监听器.因此,您在 afterTextChanged() 中得到错误的 autoComplete.getAdapter().getCount().我建议使用自定义侦听器,每次更改过滤项时都会调用该侦听器.

You cannot get correct filtered items' count in TextWatcher, because filtering usually takes longer time than TextWatcher event listeners. Therefore you get incorrect autoComplete.getAdapter().getCount() in afterTextChanged(). I would recommend to use custom listener which will be called every time when filtered items are changed.

我将提供 2 种类似的方法:使用单独的类和仅使用 1 个类.

I will provide 2 similar approaches: using separate classes and using only 1 class.

方法 1:您的适配器应如下所示:

APPROACH 1: Your adapter should look like:

import android.content.Context;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import java.util.ArrayList;
import java.util.List;

public class AutoCompleteAdapter extends ArrayAdapter
{
    private List<String>    tempItems;
    private List<String>    suggestions;
    private FilterListeners filterListeners;

    public AutoCompleteAdapter(Context context, int resource, List<String> items)
    {
        super(context, resource, 0, items);

        tempItems = new ArrayList<>(items);
        suggestions = new ArrayList<>();
    }

    public void setFilterListeners(FilterListeners filterFinishedListener)
    {
        filterListeners = filterFinishedListener;
    }

    @Override
    public Filter getFilter()
    {
        return nameFilter;
    }

    Filter nameFilter = new Filter()
    {
        @Override
        protected FilterResults performFiltering(CharSequence constraint)
        {
            if (constraint != null)
            {
                suggestions.clear();
                for (String names : tempItems)
                {
                    if (names.toLowerCase().startsWith(constraint.toString().toLowerCase()))
                    {
                        suggestions.add(names);
                    }
                }
                FilterResults filterResults = new FilterResults();
                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
                return filterResults;
            }
            else
            {
                return new FilterResults();
            }
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results)
        {
            List<String> filterList = (ArrayList<String>) results.values;

            if (filterListeners != null && filterList!= null)
                filterListeners.filteringFinished(filterList.size());

            if (results != null && results.count > 0)
            {
                clear();
                for (String item : filterList)
                {
                    add(item);
                    notifyDataSetChanged();
                }
            }
        }
    };
}

用于在过滤完成时通知您的界面:

An interface which is used to inform you when filtering will be finished:

public interface FilterListeners
{
    void filteringFinished(int filteredItemsCount);
}

你可以使用它:

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.AutoCompleteTextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity implements FilterListeners
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AutoCompleteTextView autoComplete = (AutoCompleteTextView) findViewById(R.id.autoComplete);
        autoComplete.setThreshold(1);

        List<String> stringList = new ArrayList<>();
        stringList.add("Black");
        stringList.add("White");
        stringList.add("Yellow");
        stringList.add("Blue");
        stringList.add("Brown");


        final AutoCompleteAdapter adapter = new AutoCompleteAdapter(this, android.R.layout.simple_list_item_1, stringList);
        adapter.setFilterListeners(this);
        autoComplete.setAdapter(adapter);
    }

    @Override
    public void filteringFinished(int filteredItemsCount)
    {
        Log.i("LOG_TAG", " filteringFinished  count = " + filteredItemsCount);
    }
}

方法 2:

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.ArrayAdapter;
    import android.widget.AutoCompleteTextView;
    import android.widget.Filter;
    import java.util.ArrayList;
    import java.util.List;

    public class MainActivity extends Activity
    {
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            final AutoCompleteTextView autoComplete = (AutoCompleteTextView) findViewById(R.id.autoComplete);
            autoComplete.setThreshold(1);

            final List<String> stringList = new ArrayList<>();
            stringList.add("Black");
            stringList.add("White");
            stringList.add("Yellow");
            stringList.add("Blue");
            stringList.add("Brown");

            final ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, stringList)
            {
                private List<String> tempItems   = stringList;
                private List<String> suggestions = new ArrayList<>();

                @Override
                public Filter getFilter()
                {
                    return nameFilter;
                }

                Filter nameFilter = new Filter()
                {
                    @Override
                    protected FilterResults performFiltering(CharSequence constraint)
                    {
                        if (constraint != null)
                        {
                            suggestions.clear();
                            for (String names : tempItems)
                            {
                                if (names.toLowerCase().startsWith(constraint.toString().toLowerCase()))
                                {
                                    suggestions.add(names);
                                }
                            }
                            FilterResults filterResults = new FilterResults();
                            filterResults.values = suggestions;
                            filterResults.count = suggestions.size();
                            return filterResults;
                        }
                        else
                        {
                            return new FilterResults();
                        }
                    }

                @Override
                protected void publishResults(CharSequence constraint, FilterResults results)
                {
                    List<String> filterList = (ArrayList<String>) results.values;
                    filteringFinished(filterList.size());

                    if (results != null && results.count > 0)
                    {
                        clear();
                        for (String item : filterList)
                        {
                            add(item);
                            notifyDataSetChanged();
                        }
                    }
                }
            };
        };

        autoComplete.setAdapter(arrayAdapter);
    }

    private void filteringFinished(int filteredItemsCount)
    {
        Log.i("LOG_TAG", " filteringFinished  count = " + filteredItemsCount);
    }
}

filteringFinished() 方法将在您向自动完成输入字段输入内容并被过滤时被调用.

filteringFinished() method will be called when you enter something to an autocomplete input field and it gets filtered.

更新(Trie 搜索):

我用一个简单的例子创建了一个 Github 项目,使用 Trie 搜索算法来增加自动完成性能非常好.

I have created a Github project with a simple example of using Trie search algorithm to increase autocomplete performance very much.

https://github.com/saqada/android-AutoCompleteWithTrie

这篇关于在 AutoCompleteTextview 中获取过滤后的数组大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆