ArrayAdapter是从后期在web服务更新AutoCompleteTextAdapter [英] ArrayAdapter is updated late from Webservice in AutoCompleteTextAdapter

查看:181
本文介绍了ArrayAdapter是从后期在web服务更新AutoCompleteTextAdapter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个AutocompleteTextView与ArrayAdapter工作。该适配器与Web服务,文本更改时更新。这个更新在AsyncTask的,什么是应该是一个很好的做法已经完成。这是工作多还是少,因为每一个关键pressed后的建议是基于在previous键pressed检索到的字符串。
有几个相关的问题是这样的页面,但是没有一个答案对我的作品。不管怎么说,我有一个解决方案,但效率不高,我不知道为什么官方的解决办法失败。

I have an AutocompleteTextView working with an ArrayAdapter. The adapter is updated from a webservice, when the text changes. This updated is done in an AsyncTask, what is supposed to be a good practice. This is working more or less, because the suggestions after every key pressed are based on the strings retrieved in the previous key pressed. There is a couple of problems related is this page, but none of the answers works for me. Anyway, I had a solution, but is inefficient and I don't know why the "official solution" fails.

我认为,关键是在udpates德ArrayAdapter在后台的功能。这一点,我在异步调用尽到Web服务:

I think that the key is in the function that udpates de ArrayAdapter in the background. This it what I do in the asynchronous call to the webservices:

private class DoAutoCompleteSearch extends AsyncTask<String, Void, Map<String, String>> {

    @Override
    protected Map<String, String> doInBackground(String... params) {

        // Ask the webservice for data
        Map<String, String> autoComplete = GetResource.dataList(params[0]);
        return autoComplete;
    }

    @Override
    protected void onPostExecute(Map<String, String> result) {

        //mAutoCompleteAdapter.clear();    * This should work but does not *

/* If it is set a new adapter in the AutoCompleteTextView, the whole thing works properly */

    mAutoCompleteAdapter = new ArrayAdapter<String>(mAutoCompleteAdapter.getContext(), android.R.layout.simple_dropdown_item_1line);
    mACTV.setAdapter(mAutoCompleteAdapter);

        for (Map.Entry<String, String> entry : result.entrySet()) {
            mAutoCompleteAdapter.add(entry.getKey());
        }
    }
}

我与mAutoCompleteAdapter.clear(尝试),并设置mAutoCompleteAdapter.notifyDataSetChanged()无处不在,但它是无用的。

I have tried with mAutoCompleteAdapter.clear() and setting mAutoCompleteAdapter.notifyDataSetChanged() everywhere, but it is useless.

推荐答案

我也试过很多得到这个工作的方式,但没有成功比你更好。但我发现另一种方式来完成你想要的东西;扩展ArrayAdapter和实施筛选。这个类将是从数据库中进行实际取,当由AutoCompleteTextView在辅助线程名为:

I also tried alot to get this approach working, but didn't succeed any better than yourself. But I found another way to accomplish what you want; extend ArrayAdapter and implement Filterable. This class will be doing the actual fetching from the database, when called by the AutoCompleteTextView in a worker thread:

public class MyAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {

    private List<String> mData = new ArrayList<String>();
    private Server mServer;

    public MyAutoCompleteAdapter(Server server, Context context, int textViewResourceId) {
        super(context, textViewResourceId);
        mServer = server;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public String getItem(int index) {
        return mData.get(index);
    }

    @Override
    public Filter getFilter() {
        Filter myFilter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                // This method is called in a worker thread

                FilterResults filterResults = new FilterResults();
                if(constraint != null) {
                    try {
                        // Here is the method (synchronous) that fetches the data
                        // from the server
                        List<String> results = mServer.searchForItems(constraint.toString());
                        filterResults.values = results;
                        filterResults.count = results.size();
                    }
                    catch(Exception e) {}

                }
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence contraint, FilterResults results) {
                if(results != null && results.count > 0) {
                    mData = (List<String>)results.values;
                    notifyDataSetChanged();
                }
                else {
                    notifyDataSetInvalidated();
                }
            }
        };
        return myFilter;
    }
}

修改:我已经改善上述code,因为我有时会得到异常 java.lang.IllegalStateException:适配器的内容发生了变化,但ListView控件没有收到通知。为了解决这个问题,让我感动) MDATA 的更新,以 publishResults(

EDIT: I have improved the above code since I sometimes got the exception java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. To fix this, I moved the updating of mData to publishResults().

这篇关于ArrayAdapter是从后期在web服务更新AutoCompleteTextAdapter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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