I am working on a requirement where an Auto Complete text view is used to fetch matching Localities . The user has to enter a few characters, and a list of Localities matching these characters is returned from the server. The Autocomplete Text View then should display this list as a dropdown(or popup). For some reason, even though I am receiving valid Localities from server, the autocomplete dropdown does not come up. Here is my code.
Locality (Model)
public class Locality {
private int Id;
private String name;
private boolean selected;
//Getters and Setters
}
DonorSearchFragment.xml (layout file containing AutoCompleteTextView)
<AutoCompleteTextView
android:id="@+id/actLocality"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
LocalityListAdapter View (locality_row.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
<TextView
android:id="@+id/txvLocalityName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
LocalityListAdapter.java
public class LocalityListAdapter extends ArrayAdapter<Locality> {
List<Locality> localities;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//The Current View
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.locality_row, null);
}
Locality currentLocality = localities.get(position);
if (currentLocality != null) {
TextView txvLocalityName = (TextView) view.findViewById(R.id.txvLocalityName);
txvLocalityName.setText(currentLocality.getName());
}
return view;
}
}
DonorSearchFragment.java (Fragment showing the AutoCompleteTextView)
public class DonorSearchFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
searchFragmentView = inflater.inflate(R.layout.fragment_donor_search, container, false);
//Locality AutoComplete
localityList = new ArrayList<Locality>();
AutoCompleteTextView actLocality = (AutoCompleteTextView) searchFragmentView.findViewById(R.id.actLocality);
localityListAdapter = new LocalityListAdapter(this.getActivity(), R.layout.locality_row, localityList);
actLocality.setAdapter(localityListAdapter);
actLocality.addTextChangedListener(new TextWatcher() {
...
@Override
public void afterTextChanged(Editable editable) {
new LocalitySearchTask().execute();
}
});
private class LocalitySearchTask extends AsyncTask<Void, Void, List<Locality>> {
...
protected List<Locality> doInBackground(Void... voids) {
List<Locality> localities = null;
//Call WebService and populate localities
return localities;
}
@Override
protected void onPostExecute(List<Locality> localities) {
//Refresh List backing the Adapter
//I see valid localities here, but somehow they are not shown by AutoComplete
localityListAdapter.clear();
for(Locality locality : localities){
localityList.add(locality);
}
localityListAdapter.notifyDataSetChanged();
}
}
}
In onPostExecute() I checked that I am receiving valid Localities List and then pushing them in the LocalityList backing the adapter, but these Localities are not shown by the dropdown. In fact there is no dropdown displayed. Any reasons what could be wrong or missing ?
I feel there is a better way to handle this scenario which obviates the use of AsyncTask . Instead a Filter can be used, which provides performFiltering() callback that actually runs in a worker thread. Here the matching data can be decided / prepared (like by a server call or similar). When the results are prepared the publishResults callback which runs on UI thread, can be used to modifiy the list backing the Custom Adapter. I am just beginning to understand the Android Adapters so I may be incorrect here though. Here is the code that I am using
public class LocalityListAdapter extends ArrayAdapter<Locality> {
List<Locality> localities;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.locality_row, null);
}
Locality currentLocality = localities.get(position);
if (currentLocality != null) {
TextView txvLocalityName = (TextView) view.findViewById(R.id.txvLocalityName);
txvLocalityName.setText(currentLocality.getName());
}
return view;
}
@Override
public Filter getFilter() {
return localityFilter;
}
Filter localityFilter = new Filter() {
@Override
public CharSequence convertResultToString(Object resultValue) {
Locality locality = (Locality) resultValue;
return locality.getName();
}
protected FilterResults performFiltering(CharSequence constraint) {
List<Locality> localityList = new ArrayList<Locality>();
...Get Data from Server
//Return FilterResults created from response
FilterResults filterResults = new FilterResults();
filterResults.values = localityList;
filterResults.count = localityList.size();
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
localities.clear();
List<Locality> filteredList = (List<Locality>) filterResults.values;
for(Locality locality : filteredList) {
localities.add(locality);
}
notifyDataSetChanged();
}
}
}
DonorSearchFragment.java (From MainActivity)
public class DonorSearchFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
searchFragmentView = inflater.inflate(R.layout.fragment_donor_search, container, false);
//Locality AutoComplete
localityList = new ArrayList<Locality>();
actLocality = (AutoCompleteTextView) searchFragmentView.findViewById(R.id.actLocality);
localityListAdapter = new LocalityListAdapter(this.getActivity(), R.layout.locality_row, localityList);
actLocality.setAdapter(localityListAdapter);
...
return searchFragmentView;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.