自定义ArrayAdapter getFilter()未被调用

时间:2015-11-16 13:20:46

标签: java android

在一个曾经使用ArrayList和ArrayAdapter来填充AutoCompleteTextView的简单Android应用程序中,我现在已经用自定义适配器替换了ArrayAdapter。原因是我需要在搜索列表之前从输入的文本中删除空格和其他一些字符(即输入" OM"应该标准化为" OM"然后建议以&#34开头;应显示OM"

我尝试在GitHub上的以下提交中执行此操作:https://github.com/Natureshadow/MirWTFApp/commit/260a4deaee449cb63d3af3c446c94466b90f736c

自定义适配器有一个getFilter方法,该方法应该返回一个执行规范化的自定义Filter,但是从不调用getFilter()。

我该怎么做才能找出未调用的原因,以及如何让应用使用自定义过滤器?

StackOverflow有一些问题描述了类似的问题,但所有这些问题都包括改变自定义适配器中ArrayList数据的处理,我没有这样做。

2 个答案:

答案 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必须能够从ArrayFilterArrayAdapter的内部私有类)调用方法,因此它必须属于package android.widget;。我将免除你full imports, comments, etc.并重现以下重要部分:

public class WtfArrayAdapter<T> extends ArrayAdapter<T> {

新成员: - 预过滤器规范化方法的对象 - 我们的内部私有类'对象 - 不幸的是,父级的内部私有类'对象(ArrayAdapter.mFilterprivate

    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);
            }
        });