I have created a custom ArrayAdapter
so I can filter the results to my AutoCompleteTextView
:
public class AutoCompleteCountryAdapter extends ArrayAdapter<String>
{
private List<String> countryListFull;
public AutoCompleteCountryAdapter(@NonNull Context context, int resource, @NonNull List<String> countryList)
{
super(context, resource, countryList);
countryListFull = new ArrayList<>(countryList);
}
@NonNull
@Override
public Filter getFilter()
{
return countryFilter;
}
private Filter countryFilter = new Filter()
{
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults filterResults = new FilterResults();
List<String> suggestions = new ArrayList<>();
if (constraint == null || constraint.length() == 0)
{
suggestions.addAll(countryListFull);
} else
{
String filterPattern = constraint.toString().toLowerCase().trim();
for (String country : countryListFull)
{
if (country.toLowerCase().startsWith(filterPattern))
{
suggestions.add(country);
}
}
}
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults)
{
clear();
addAll((List) filterResults.values);
notifyDataSetChanged();
}
@Override
public CharSequence convertResultToString(Object resultValue)
{
return ((String) resultValue);
}
};
}
However, when I try to use this adapter:
List<String> placeOfBirthList;
AutoCompleteCountryAdapter pobAdapter = new AutoCompleteCountryAdapter(new AutoCompleteCountryAdapter(getApplication().getApplicationContext(), android.R.layout.simple_dropdown_item_1line, placeOfBirthList));
I get this Logcat error:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
I get this exception at the line that is the first curly brace after creating a new Filter:
private Filter countryFilter = new Filter()
{ // HERE
I am not calling this from my MainActivity.java
, but from a normal method within the ViewModel
of a Fragment
of a different activity.
public class MyViewModel extends AndroidViewModel {
private List<String> placeOfBirthList;
public MyViewModel(Application application) {
super(application);
myMethod();
}
private void myMethod() {
AutoCompleteCountryAdapter myAdapter = new AutoCompleteCountryAdapter(getApplication().getApplicationContext(), android.R.layout.simple_dropdown_item_1line, placeOfBirthList);
}
}
So ... I fixed the problem. At the suggestion of a colleague, I moved the creation of the custom ArrayAdapter into my View fragment:
FragmentBinding binding = ~~~;
MyViewModel mViewModel = ~~~;
binding.setViewModel(mViewModel);
AutoCompleteCountryAdapter myAdapter = new AutoCompleteCountryAdapter(getContext(), android.R.layout.simple_dropdown_item_1line, viewModel.getPlaceOfBirthList());
binding.placeOfBirthField.setAdapter(myAdapter);
And this fixed all of my Looper issues. Plus, it satisfies the "no view code in the view model" requirements of MVVM.