在尝试使用我的自定义 Android ArrayAdapter 时,我不知道如何克服这个 Looper.prepare() 错误
I cannot figure out how to get past this Looper.prepare() error when trying to use my custom Android ArrayAdapter
我创建了自定义 ArrayAdapter
,因此我可以将结果过滤到我的 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);
}
};
}
但是,当我尝试使用此适配器时:
List<String> placeOfBirthList;
AutoCompleteCountryAdapter pobAdapter = new AutoCompleteCountryAdapter(new AutoCompleteCountryAdapter(getApplication().getApplicationContext(), android.R.layout.simple_dropdown_item_1line, placeOfBirthList));
我收到这个 Logcat 错误:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
我在创建新过滤器后的第一个花括号行得到这个异常:
private Filter countryFilter = new Filter()
{ // HERE
我不是从我的 MainActivity.java
调用它,而是从另一个 activity 的 Fragment
的 ViewModel
中的普通方法调用。
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);
}
}
所以...我解决了这个问题。在同事的建议下,我将自定义 ArrayAdapter 的创建移到了我的视图片段中:
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);
这解决了我所有的 Looper 问题。另外,它满足 MVVM 的 "no view code in the view model" 要求。
我创建了自定义 ArrayAdapter
,因此我可以将结果过滤到我的 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);
}
};
}
但是,当我尝试使用此适配器时:
List<String> placeOfBirthList;
AutoCompleteCountryAdapter pobAdapter = new AutoCompleteCountryAdapter(new AutoCompleteCountryAdapter(getApplication().getApplicationContext(), android.R.layout.simple_dropdown_item_1line, placeOfBirthList));
我收到这个 Logcat 错误:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
我在创建新过滤器后的第一个花括号行得到这个异常:
private Filter countryFilter = new Filter()
{ // HERE
我不是从我的 MainActivity.java
调用它,而是从另一个 activity 的 Fragment
的 ViewModel
中的普通方法调用。
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);
}
}
所以...我解决了这个问题。在同事的建议下,我将自定义 ArrayAdapter 的创建移到了我的视图片段中:
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);
这解决了我所有的 Looper 问题。另外,它满足 MVVM 的 "no view code in the view model" 要求。