2015-06-18 3 views
2

Самый эффективный (с точки зрения количества подключений) Реализация AutoCompleteTextView, которую я нашел, представляет собой DelayAutoCompleteTextView, предложенный here. Тем не менее, я думаю, что его можно улучшить, не спрашивая данные, о которых вы ранее просили. То есть, представьте, что AutoCompleteTextView подключен к веб-службе и извлекает данные об английском словаре. Затем, если пользователь пишет «Яйцо», AutoCompleteTextView будет запрашивать веб-службу для слов, содержащих «Яйцо», например [«Яйцо», «Яйцо-голова», «Эггед», «Эггинг», «Яйца», .. .], и этот список будет показан пользователю. Тем не менее, если пользователь уточняет запрос, набрав еще одну букву (т. Е. «Eggi»), AutoCompleteTextView запросит «снова» веб-сервер для слов, содержащих «Eggi», и вот что я думаю, что можно улучшить. Зачем нам нужно запрашивать у веб-службы информацию, которую мы уже имеем? Слова, содержащие «Eggi», включены в те, которые содержат «Egg», поэтому нет необходимости спрашивать сервер, вместо этого мы должны отфильтровать первый список, который мы получаем из веб-службы.эффективный AutoCompleteTextView

Кто-нибудь знает, как это сделать?

Спасибо!

ответ

0

У меня есть возможное решение. Может быть, он может быть улучшен (может ли кто-нибудь подумать в лучшем подходе?)

Следующий код (вдохновленный this) является адаптером, который реализует Filterable. Новая часть находится внутри метода getFilter, где я проверяю, является ли ограничение фильтра более строгим, чем предыдущее. Если это так, я не хочу просить веб-сервис, так как информация уже находится в полученном ранее списке результатов, запрашивая у webservice предыдущий 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); 
}} 

Пожалуйста, если вы знаете, как это сделать лучше, дайте мне знать.

Смежные вопросы