高效的AutoCompleteTextView [英] efficient AutoCompleteTextView
问题描述
我发现最有效的(就连接数量而言)AutoCompleteTextView实现是建议的DelayAutoCompleteTextView
The most efficient (in terms of amount of connections) AutoCompleteTextView implementation I found is the DelayAutoCompleteTextView proposed here. However, I think that it can be improved by do not ask for data that you previously asked for. That is, imagine that the AutoCompleteTextView is connected to a web service and retrieves data about a English Dictionary. Then, if the user writes "Egg", the AutoCompleteTextView will ask to the web service for words containing "Egg" like ["Egg", "Egg-head", "Egged", "Egging", "Eggs", ...] and this list is the one will be showed to the user. Nevertheless, if the user refines the query by typing one more letter (i.e., "Eggi"), the AutoCompleteTextView will ask 'again' to the web server for words containing "Eggi" and here is what I think that can be improved. Why do we need to ask to the web service for information we already have? Words containing "Eggi" are included in the ones containing "Egg" so there is no need to ask to the server, instead we must filter the first list we get from the web service.
有人知道该怎么做吗?
谢谢!
推荐答案
我对此有可能的解决方案.也许可以改进(有人可以考虑采用更好的方法吗?)
I have a possible solution to this. Maybe it can be improved (could anyone think in a better approach?)
以下代码(灵感来自此)是实现Filterable的适配器.新的部分在getFilter方法内部,在该方法中,我检查过滤器约束是否比前一个约束更严格.如果是这种情况,我不想向Web服务询问,因为该信息已经存在于先前通过查询具有先前约束的Web服务而获得的resultList中,该限制较少.
The following code (inspired by this) is an Adapter that implements Filterable. The new part is inside getFilter method where I check if the filter constraint is more restrictive than the previous one. If this is the case I don't want to ask to the webservice since the information is already in the resultList obtained previously by asking the webservice with the previous constrint, which was less restrictive.
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);
}}
如果您知道如何更好地做到这一点,请告诉我.
Please if you know how to do this better let me know.
这篇关于高效的AutoCompleteTextView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!