在一个曾经使用ArrayList和ArrayAdapter来填充AutoCompleteTextView的简单Android应用程序中,我现在已经用自定义适配器替换了ArrayAdapter。原因是我需要在搜索列表之前从输入的文本中删除空格和其他一些字符(即输入" OM"应该标准化为" OM"然后建议以&#34开头;应显示OM"
我尝试在GitHub上的以下提交中执行此操作:https://github.com/Natureshadow/MirWTFApp/commit/260a4deaee449cb63d3af3c446c94466b90f736c
自定义适配器有一个getFilter方法,该方法应该返回一个执行规范化的自定义Filter,但是从不调用getFilter()。
我该怎么做才能找出未调用的原因,以及如何让应用使用自定义过滤器?
StackOverflow有一些问题描述了类似的问题,但所有这些问题都包括改变自定义适配器中ArrayList数据的处理,我没有这样做。
答案 0 :(得分:1)
该解决方案最终成为一个自定义ArrayAdapter
子类,它在ArrayFilter
甚至看到之前预先设置了一个过滤器。
对主应用程序的更改是最小的,它只需要实例化新命名的WtfArrayAdapter
并向其构造函数传递一个额外的参数:对包含规范化方法的对象的对象引用(在当前的äpp设计中) ,那是MainActivity
类,未来的重构会做得更好):
- ArrayAdapter acronymKeys = new ArrayAdapter(this,
- android.R.layout.simple_list_item_1, sorted);
+ ArrayAdapter acronymKeys = new WtfArrayAdapter(this,
+ android.R.layout.simple_list_item_1, sorted, this);
自定义WtfArrayAdapter
必须能够从ArrayFilter
(ArrayAdapter
的内部私有类)调用方法,因此它必须属于package android.widget;
。我将免除你full imports, comments, etc.并重现以下重要部分:
public class WtfArrayAdapter<T> extends ArrayAdapter<T> {
新成员:
- 预过滤器规范化方法的对象
- 我们的内部私有类'对象
- 不幸的是,父级的内部私有类'对象(ArrayAdapter.mFilter
为private
)
private MainActivity sParent;
private WtfArrayFilter sFilter;
private Filter pFilter;
扩展构造函数(我们只需要实现我们实际调用的那个):
- 调用继承的构造函数
- 存储父项的mFilter
值
- 实例化我们自己的WtfArrayFilter
- 存储预过滤器规范化方法的对象,因为WtfArrayFilter
稍后将需要它
public WtfArrayAdapter(Context context, @LayoutRes int resource,
@NonNull T[] objects, MainActivity parent) {
super(context, resource, 0, Arrays.asList(objects));
sParent = parent;
sFilter = new WtfArrayFilter();
pFilter = super.getFilter();
}
覆盖ArrayAdapter
的{{1}}方法,以便始终返回新的getFilter()
:
WtfArrayFilter
public Filter getFilter() {
return sFilter;
}
作为WtfArrayFilter
子类实现,就像Filter
一样,并将所有无聊(即未更改)的调用转发给继承的ArrayFilter
:
ArrayFilter
在调用继承的 private class WtfArrayFilter extends Filter {
protected void publishResults(CharSequence constraint,
FilterResults results) {
pFilter.publishResults(constraint, results);
}
过滤方法之前,我们只需要更改一个方法来进行自己的过滤:
ArrayFilter
欢迎改进,我仍然是Java™初学者。
答案 1 :(得分:0)
ArrayList<YourModel> listFromActivity= null;
ArrayList<YourModel> mainList;
public MyConstructor(Context context, ArrayList<YourModel> listFromActivity) {
this.context = context;
this.listFromActivity= listFromActivity;
mainList= new ArrayList<>();
mainList.addAll(listFromActivity);
}
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
mainList.clear();
if (charText.length() == 0) {
mainList.addAll(arraylist);
} else {
for (YourObject wp : arraylist) {
if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText) ||
wp.getKey().contains(charText)) {
mainList.add(wp);
}
}
}
notifyDataSetChanged();
}
以及使用此适配器时的活动或片段
edittext.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String text = mSearch.getText().toString().toLowerCase(Locale.getDefault());
adaper.filter(text);
}
});