动态更新AutoCompleteTextView在选中项目后再次弹出下拉列表

时间:2011-11-23 19:37:01

标签: java android autocomplete

我正在动态更新AutoCompleteTextView,我遇到两个问题。

  • 当选择了项目时,会有一个新的onTextChanged事件,正如您在下面的代码中看到的那样,有一个新的请求来获取新的可选项,因此onTextChanged事件会导致AutoComplete再次显示下拉列表!有没有一个干净的方法来解决它?!

  • 在我调用notifyDataSetChange()之前,我从自动完成获得的结果来自之前的适配器,我该如何实现?!

这是代码:

AutoCompleteTextView acCountry = (AutoCompleteTextView)layout.findViewById(R.id.autoComplete);
final ArrayAdapter<RMAutoComplete.ListItem> countriesAdapter = new ArrayAdapter<RMAutoComplete.ListItem>(this.context,android.R.layout.simple_dropdown_item_1line);
acCountry.setAdapter(countriesAdapter);
acCountry.addTextChangedListener(new TextWatcher() {

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.length() > 1)
            {
                new AsyncTask<String, Void, List<RMAutoComplete.ListItem>>(){

                    @Override
                    protected List<ListItem> doInBackground(String... params) {
                        List<ListItem> l = null;
                        try {
                            l = location.getCountryData(params[0]);
                        } catch (Exception e) {
                            Log.e(TAG,"error when getCountryData",e);
                        }
                        return l;
                    }

                    @Override
                    protected void onPostExecute(List<ListItem> countries) {
                        countriesAdapter.clear();
                        if (countries != null)
                            for (ListItem listItem : countries) {
                                countriesAdapter.add(listItem);
                            }
                        countriesAdapter.notifyDataSetChanged();
                    }
                }.execute(s.toString());
            }
        }

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

        public void afterTextChanged(Editable s) {}
    }
);

1 个答案:

答案 0 :(得分:3)

要获得动态适配器,需要做的是实现自定义过滤器类并覆盖performFiltering和publishResults方法。

在performFiltering中创建 FilterResults 的新实例并初始化其值并使用新项计数..(此方法默认在新线程上有效!)类似于:

@Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults fr = null;
        if (constraint != null)
        {
            List<ListItem> list = getFilterdValues(constraint.toString());

            if (list != null)
            {
                fr = new FilterResults();
                fr.values = list;
                fr.count = list.size();
            }
        }
        return fr;
    }

并在publishResults中将结果添加到适配器,如下所示:

@Override
    protected void publishResults(CharSequence constraint,
            FilterResults results) {
        AutoCompleteAdapter.this.clear();
        if (results != null)
        {
            if (results.values != null)
            {
                List<ListItem> items = (List<ListItem>) results.values;

                    for (ListItem listItem : items) {
                        AutoCompleteAdapter.this.add(listItem);
                    }

                if (items.size() > 0)
                {
                    AutoCompleteAdapter.this.notifyDataSetChanged();
                    return;
                }
            }
        }
        AutoCompleteAdapter.this.notifyDataSetInvalidated();
    }

同样重要的是你需要自定义适配器并使用你自己的新自定义Filter类覆盖getFilter,如下所示:

public class AutoCompleteAdapter extends ArrayAdapter<RMAutoComplete.ListItem> 
{


private CustomFilter _customFilter = null;

@Override
public Filter getFilter() {

    if (_customFilter == null)
        _customFilter = new CustomFilter();
    return _customFilter;
}


public AutoCompleteAdapter(Context context, int textViewResourceId) {
    super(context, textViewResourceId);

}

}

希望这对某人有帮助..