【问题标题】:How to set AutocompleteTextView to perform only one filter search at a time and set a delay before starting the filtering?如何设置 AutocompleteTextView 一次只执行一个过滤器搜索并在开始过滤之前设置延迟?
【发布时间】:2014-05-05 15:57:19
【问题描述】:

我有这个与 AutocompleteTextView 相关的问题。基本上,我已经实现了一个带有自定义过滤器的自定义适配器,该过滤器过滤了自定义对象列表,并且一切正常,除了当我在 autocompleteTextView 中以快速方式键入时,似乎启动了工作过滤器线程队列并且键入和过滤本身变得非常缓慢。如何根据用户的最新输入一次只设置一个过滤器(如果它实际运行,则取消前一个过滤器线程)并在开始过滤之前设置一个小的延迟,这样当用户快速键入时,自动完成不会慢???

谢谢!

编辑:我有这个带有过滤器实现的自定义适配器:

public class MunicipalitySearchAdapter extends ArrayAdapter<Municipality> {

private ArrayList<Municipality> municipalities;
private ArrayList<Municipality> allMunicipalities;
private ArrayList<Municipality> suggestedMunicipalities;

private List<Trieable> triableList;

private Trie municipalityTrie;

private int viewResourceId;

@SuppressWarnings("unchecked")
public MunicipalitySearchAdapter(Context context, int viewResourceId, ArrayList<Municipality> municipalities) {
    super(context, viewResourceId, municipalities);
    this.municipalities = municipalities;
    this.allMunicipalities = (ArrayList<Municipality>) this.municipalities.clone();
    this.suggestedMunicipalities = new ArrayList<Municipality>();
    this.viewResourceId = viewResourceId;
    this.triableList = new ArrayList<Trieable>();
    for (Municipality mun : allMunicipalities) {
        triableList.add(mun);
    }
    municipalityTrie = new Trie(triableList, Locale.ITALY);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(this.viewResourceId, null);
    }
    Municipality municipality = municipalities.get(position);
    if (municipality != null) {
        TextView munNameTxtView = (TextView) v.findViewById(R.id.name);
        TextView proSignTxtView = (TextView) v.findViewById(R.id.sign);
        TextView regNameTxtView = (TextView) v.findViewById(R.id.regionName);

        if (munNameTxtView != null) {
            munNameTxtView.setText(municipality.getName());
        }
        if (proSignTxtView != null) {
            proSignTxtView.setText(municipality.getProvinceSign());
        }
        if (regNameTxtView != null) {
            regNameTxtView.setText(municipality.getRegionName());
        }
    }
    return v;
}

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

Filter municipalityFilter = new Filter() {      
    CharSequence filterConstraint;
    @Override
    public String convertResultToString(Object resultValue) {
        String str = ((Municipality) (resultValue)).getName();
        return str;
    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults filterRes = new FilterResults();
        synchronized (filterRes) {
            if (this.filterConstraint == null) {
                this.filterConstraint = constraint;
            }

            if (constraint == null || constraint.length() == 0) {
                filterRes.values = allMunicipalities;
                filterRes.count = allMunicipalities.size();
            }

            else {
                String constraintString = constraint.toString().trim().toLowerCase(Locale.ITALY);
                suggestedMunicipalities.clear();

                List<Integer> wordsIndexesList = municipalityTrie.getWordsIndexes(municipalityTrie.getRootVertex(), constraintString);
                for (int index : wordsIndexesList) {
                    suggestedMunicipalities.add(allMunicipalities.get(index));
                }

                List<Integer> prefixesIndexesList = municipalityTrie.getPrefixesIndexes(municipalityTrie.getRootVertex(), constraintString);
                for (int index : prefixesIndexesList) {
                    suggestedMunicipalities.add(allMunicipalities.get(index));
                }

                filterRes.values = suggestedMunicipalities;
                filterRes.count = suggestedMunicipalities.size();                   
            }
        }

        return filterRes;

    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        if (results != null && results.count > 0) {
            synchronized (results) {
                @SuppressWarnings("unchecked")
                ArrayList<Municipality> filteredMunicipalities = (ArrayList<Municipality>) results.values;
                ArrayList<Municipality> supportMunicipalitiesList = new ArrayList<Municipality>();

                clear();
                for (Municipality mun : filteredMunicipalities) {
                    supportMunicipalitiesList.add(mun);
                }
                Iterator<Municipality> municipalityIterator = supportMunicipalitiesList.iterator();
                while (municipalityIterator.hasNext()) {
                    Municipality municipality = municipalityIterator.next();
                    add(municipality);
                }
                notifyDataSetChanged();
            }
        }           
    }
};
}

如何让 Loader 管理这个过滤器工作线程?

【问题讨论】:

标签: java android multithreading filter autocompletetextview


【解决方案1】:

最好的方法是使用加载器。在 textinput 更改时重新启动加载程序以搜索当前文本。因此,如果已经有一个具有相同 ID 的加载器正在运行,它将重新启动。这将确保您将获得 last input 的结果。我在 Play 商店中的一个应用程序中使用了这种方法。

   getLoaderManager().restartLoader(0, bundle, callback);
 // 0 - I'd
// pass the input text through bundle
// callback - loader callback

注意:第一次搜索可以调用restart,如果不存在就会创建。

如果您不知道加载程序,请查看此链接 http://developer.android.com/guide/components/loaders.html

【讨论】:

  • 感谢您的回复,我已阅读您发布的加载程序指南。抱歉,关于这个有趣的话题,我想问你一些问题。 “因此,如果已经有一个具有相同 ID 的加载器正在运行,它将被重新启动”意味着先前具有相同 ID 的加载器将被销毁,并且将创建另一个具有相同 ID 的加载器(因此将调用 onCreateLoader())?你为什么要传递一个捆绑包? Callback 可能是 Filter 类的 filter() 调用???
  • 它没有完全重新创建加载器,当前正在运行的工作将被停止并开始新的工作。 bundle只是传数据给回调,可以为null。
  • 所以如果我有一个过滤器(Charset s),我可以这样做:getLoaderManager().restartLoader(0, bundle, myAdapter.getFilter().filter(s)); ?那么Loader会运行过滤吗?
  • 否,第三个参数是加载器回调,以响应加载器的响应。
  • 对不起,我不明白。如何将此 Loader 调用集成到我的过滤器方法中(我将代码发布在 EDIT 标签中)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多