高效的AutoCompleteTextView

时间:2015-06-18 08:23:11

标签: android autocompletetextview

最有效的(就连接数而言)我发现的AutoCompleteTextView实现是提出的{A-3}}的DelayAutoCompleteTextView。但是,我认为可以通过不要求您之前要求的数据来改进它。也就是说,假设AutoCompleteTextView连接到Web服务并检索有关英语词典的数据。然后,如果用户写“Egg”,AutoCompleteTextView将向Web服务请求包含“Egg”的单词,如“Egg”,“Egg-head”,“Egged”,“Egging”,“Eggs”,.. 。]这个列表将会显示给用户。然而,如果用户通过再输入一个字母(即“Eggi”)来细化查询,则AutoCompleteTextView将再次向Web服务器询问包含“Eggi”的单词,这就是我认为可以改进的内容。为什么我们需要向Web服务询问我们已有的信息?包含“Eggi”的单词包含在包含“Egg”的单词中,因此无需向服务器询问,而是必须过滤我们从Web服务获得的第一个列表。

有谁知道怎么做?

谢谢!

1 个答案:

答案 0 :(得分:0)

我有一个可能的解决方案。也许它可以改进(有人能用更好的方法思考吗?)

以下代码(受this启发)是实现Filterable的适配器。新部分在getFilter方法中,我检查过滤器约束是否比前一个更严格。如果是这种情况,我不想要求webservice,因为信息已经在之前获得的resultList中,通过向web服务询问前一个constrint,这个限制较少。

public class CityAutoCompleteAdapter extends BaseAdapter implements Filterable {

private static final int MAX_RESULTS = 10;
private Context mContext;
private List<City> resultList = new ArrayList<City>();
private CharSequence previous_constraint = "";

public CityAutoCompleteAdapter(Context context) {
    mContext = context;
}

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

@Override
public City getItem(int index) {
    return resultList.get(index);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.suggestion_list, parent, false);
    }
    TextView tv = (TextView) convertView.findViewById(R.id.text1);
    tv.setText(getItem(position).getNombre() + " (" + getItem(position).getProvincia() + ")");
    tv.setTag(getItem(position).getId_pueblo());
    return convertView;
}

@Override
public Filter getFilter() {
    Filter filter = new Filter() {
        @Override
        protected android.widget.Filter.FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            if (constraint != null) {

                // checking if the new constraint is more general than the previous_constraint one
                int constraints_diff = constraint.toString().compareToIgnoreCase(previous_constraint.toString());

                if (constraints_diff >= 0 && !previous_constraint.equals("")){
                    // the new constraint is more specific than the previous_constraint one
                    List<City> filteredResultList = new ArrayList<City>();

                    // filtering data from resultList instead of retreiving again data from a web service
                    for(City city : resultList){
                        if (city.getName().toLowerCase().startsWith(constraint.toString().toLowerCase())){
                            filteredResultList.add(city);
                        }
                    }
                    // Assign the data to the FilterResults
                    filterResults.values = filteredResultList;
                    filterResults.count = filteredResultList.size();
                }else {
                    // the new constraint is more general than the previous_constraint one
                    // retreiving data from a web service
                    List<City> cities = findCities(mContext, constraint.toString());

                    // Assign the data to the FilterResults
                    filterResults.values = cities;
                    filterResults.count = cities.size();
                }
                previous_constraint = constraint;
            }
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, android.widget.Filter.FilterResults results) {
            if (results != null && results.count > 0) {
                resultList = (List<City>) results.values;
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }};
    return filter;
}

/**
 * Returns a search result for the given city name.
 */
private List<City> findCities(Context context, String city_name) {
    WebServiceWrapper wsWrapper = new WebServiceWrapper(context, MAX_RESULTS);
    return wsWrapper.getCities(city_name);
}}

如果您知道如何做到这一点,请告诉我。