Android에서 동적 자동 완성 텍스트보기를 만들었습니다. 그것은 다음과 같은 구성 요소를 가지고 있습니다.동적 자동 완성을 위해 perfromFilter에서 AsyncTask를 호출합니다.
- 내 사용자 정의 POJO가있는 ArrayAdapter.
- 어댑터 구현 가능 필터링 가능.
- 이 필터는 가져 오는 문자 또는 제약 조건을 기반으로 모든 데이터를 가져 오는 AsyncTask를 호출합니다.
- 모든 데이터를 가져온 후에 AsyncTask는 데이터를 구문 분석 한 다음 목록을 필터로 반환하여 게시합니다.
시나리오는 : 나는 첫 번째 문자를 입력 한 후, AutoCompleteTextView에에 입력을 시작하면 는 지금, 그것은 비동기 호출을 시작합니다. 그런 다음 더 많은 문자를 입력하기 시작하면 각 문자에 대해 비동기를 다시 호출하고 필터를 통해 결과를 게시합니다.
문제 : 문제는 첫째 AsyncTask를이 첫 번째 문자에 대해 호출 될 때 나는 여전히 텍스트 뷰에 입력 해요 동안, 결과 목록의 AutoCompleteTextView에의 드롭 다운에 발표된다는 점이다. 그런 다음 각 문자가 비동기 적으로 실행될 때까지 많은 시간이 소요되는 최신 목록이 게시 될 때까지 기다려야합니다.
코드 : 다음은 사용중인 어댑터입니다.
public class LocationAutoCompleteAdapter extends ArrayAdapter<LocationBean> implements Filterable {
Context context;
LayoutInflater inflater;
ArrayList<LocationBean> list, tempList, suggestions;
Filter nameFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
try {
// Downloads location list
DownloadLocations exec = new DownloadLocations();
String term = constraint.toString();
Log.e(Constants.TAG, "CHARACTER: " + term);
if (exec.getStatus() == AsyncTask.Status.RUNNING) {
exec.cancel(true);
} else {
list = exec.execute(term).get();
}
} catch (Exception e) {
e.printStackTrace();
}
filterResults.values = list;
filterResults.count = list.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
List<LocationBean> filterList = (ArrayList<LocationBean>) results.values;
if (results != null && results.count > 0) {
clear();
for (LocationBean locations : filterList) {
add(locations);
notifyDataSetChanged();
}
}
}
};
@Override
public Filter getFilter() {
return nameFilter;
}
public LocationAutoCompleteAdapter(Context context) {
super(context, R.layout.location_autocomplete_list_item);
this.context = context;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
suggestions = new ArrayList<LocationBean>();
}
public LocationAutoCompleteAdapter(Context context, ArrayList<LocationBean> list) {
super(context, R.layout.location_autocomplete_list_item, list);
this.context = context;
this.list = list;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
tempList = new ArrayList<LocationBean>(list); // this makes the difference.
suggestions = new ArrayList<LocationBean>();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.location_autocomplete_list_item, parent, false);
holder.name = (TextView) convertView.findViewById(R.id.autcom_name);
holder.state = (TextView) convertView.findViewById(R.id.autcom_state);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (list.get(position).getState().isEmpty()) {
holder.state.setVisibility(View.GONE);
} else {
holder.state.setVisibility(View.VISIBLE);
}
holder.name.setText(list.get(position).getName());
holder.state.setText(list.get(position).getState());
return convertView;
}
class ViewHolder {
TextView name, state;
}
private class DownloadLocations extends AsyncTask<String, Void, ArrayList<LocationBean>> {
@Override
protected ArrayList<LocationBean> doInBackground(String... params) {
if (!isCancelled()) {
try {
//Create a new COUNTRY SEARCH url Ex "search.php?term=india"
URL url = new URL(Api.LOCATION_URL + params[0]);
HttpsURLConnection conn = Constants.getInitHttpsURLConnectionGET(url);
String locationResponse = Constants.getStringFromConnection(conn);
// INIT ArrayList
ArrayList locationList = new ArrayList<LocationBean>();
locationList.clear();
// PARSE RESPONSE
JSONObject locationResponseJsonObject = new JSONObject(locationResponse);
Log.e(Constants.TAG, "RESPONSE: " + locationResponseJsonObject);
JSONArray result = locationResponseJsonObject.getJSONArray(Constants.KEY_LOCATION_RESULTS);
for (int i = 0; i < result.length(); i++) {
JSONObject locationObject = result.getJSONObject(i);
String id = locationObject.getString(Constants.KEY_LOCATION_ID);
String state = locationObject.getString(Constants.KEY_LOCATION_STATE);
String name = locationObject.getString(Constants.KEY_LOCATION_NAME);
String district = locationObject.getString(Constants.KEY_LOCATION_TEXT);
locationList.add(new LocationBean(id, name, district, state));
}
return locationList;
} catch (Exception e) {
Log.d("HUS", "EXCEPTION " + e);
return null;
}
} else {
return null;
}
}
}
}
내 생각 : 나는이 결과가 좋은 해결책이 될 것이다 발행하기 전에 실행 AsyncTask를 죽이고 있다고 생각합니다. 하지만 그렇게 할 수는 없습니다. 더 나은 해결책이 있거나 제 목표를 달성하는 방법을 제안하십시오.
문제를 이해하지 못했다면 알려주십시오. 그것 치명적인 것이 아니라 그 성가신 버그.
감사합니다.
Filter
가 AsyncTask
실제로 유사합니다
당신은 어떤 위치의 총 알 수 있습니까? –
@SohailZahid : 항상 변화하므로 Mumbai를 타이핑하기 시작하면 먼저 M, MU, MUM 등으로 시작하는 모든 장소를 가져옵니다. 총 장소 수는 lacs 이상이므로이 접근법을 사용했습니다. –