ListView过滤问题Android

时间:2014-07-23 04:48:58

标签: java android android-listview android-edittext android-arrayadapter

我正在尝试将一个搜索文本字段添加到我的listview中以进行一些过滤,而我的列表适配器使用自定义对象而不是简单的字符串。搜索似乎乍一看,但如果删除过滤字符串,适配器不会更新。

以下是我的尝试:

这是我的自定义ArrayAdapter

    public class ArticolAdapter extends OrderManagerAdapter<Articol> implements Scrollable {
    private List<Articol> orderList;
    private final LayoutInflater inflater;
    private final Context context;

    public ArticolAdapter(Context context, List<Articol> objects) {
        super(context, objects);
        this.inflater = LayoutInflater.from(context);
        this.orderList = objects;
        this.context = context;
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_articol, parent, false);
            holder = new ViewHolder();

            holder.name = (TextView) convertView.findViewById(R.id.numeTV);
            holder.deLivrat = (TextView) convertView.findViewById(R.id.de_livrat);
            holder.articolPoza = (ImageView) convertView.findViewById(R.id.pictureCategory);
            holder.observatiiTV = (TextView) convertView.findViewById(R.id.observatii);
            holder.incarcatTV = (TextView) convertView.findViewById(R.id.incarcat);
            holder.background = (RelativeLayout) convertView.findViewById(R.id.expandable_toggle_button);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        final Articol articol = getItem(position);
        holder.name.setText(articol.getNume());
        System.out.println(articol.getNume());
        holder.deLivrat.setText("De livrat: " + Constants.DF.format(articol.getComandat()));
        holder.incarcatTV.setText("Incarcat: " + fmt(articol.getIncarcat()));
        holder.observatiiTV.setText("Observatii: " + articol.getObservatii());
        holder.background.setPadding(5, 5, 5, 5);
        if (articol.getComandat() == articol.getIncarcat()) {
            holder.background.setBackground(context.getResources().getDrawable(R.drawable.list_item_completed));
        } else {
            holder.background.setBackground(context.getResources().getDrawable(R.drawable.list_item_bg));
        }
        return convertView;
    }

    public static String fmt(double d) {
        if (d == (int) d)
            return String.format("%d", (int) d);
        else
            return String.format("%s", d);
    }

    @Override
    public String getIndicatorForPosition(int childposition, int groupposition) {
        return Character.toString(orderList.get(childposition).getNume().charAt(0));
    }

    @Override
    public int getScrollPosition(int childposition, int groupposition) {
        return childposition;
    }

    private class ViewHolder {
        private TextView name, deLivrat, observatiiTV, incarcatTV;
        private ImageView articolPoza;
        private RelativeLayout background;
    }

    private List<Articol> orig;

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                final FilterResults oReturn = new FilterResults();
                final ArrayList<Articol> results = new ArrayList<Articol>();
                if (orig == null) {
                    orig = orderList;
                }
                if (constraint != null) {
                    if (orig != null && orig.size() > 0) {
                        for (final Articol g : orig) {
                            if (g.getNume().toLowerCase()
                                    .contains(constraint.toString())) {
                                results.add(g);
                            }
                        }
                    }
                    oReturn.values = results;
                }
                return oReturn;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint,
                                          FilterResults results) {
                orderList = (ArrayList<Articol>) results.values;
                notifyDataSetChanged();
                clear();
                for (Articol anOrderList : orderList) {
                    add(anOrderList);
                }
                notifyDataSetInvalidated();
            }
        };
    }

}

OrderManagerAdapter

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

    private final List<T> objects;
    private final Object mLock;

    public OrderManagerAdapter(Context context) {
        super(context, 0);
        objects = new ArrayList<T>();
        mLock = new Object();
        setNotifyOnChange(false);
    }

    public OrderManagerAdapter(Context context, List<T> objects) {
        super(context, 0);
        this.objects = objects;
        mLock = new Object();
    }

    @Override
    public void add(T object) {
        synchronized (mLock) {
            objects.add(object);
        }
    }

    @Override
    public void addAll(Collection<? extends T> collection) {
        synchronized (mLock) {
            objects.addAll(collection);
        }
    }

    @Override
    public void insert(T object, int index) {
        synchronized (mLock) {
            objects.add(index, object);
        }
    }

    @Override
    public void remove(T object) {
        synchronized (mLock) {
            objects.remove(object);
        }
    }

    @Override
    public void clear() {
        synchronized (mLock) {
            objects.clear();
        }
    }

    @Override
    public int getCount() {
        return objects.size();
    }

    @Override
    public T getItem(int position) {
        return objects.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getPosition(T item) {
        return objects.indexOf(item);
    }

    public List<T> getObjects() {
        return objects;
    }
}

这是片段中的EditText代码:

EditText inputSearch = (EditText) rootView.findViewById(R.id.inputSearch);
        inputSearch.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) {
                Log.d(Constants.TAG, "*** Search value changed: " + s.toString());
                adapter.getFilter().filter(s);
            }
        });

搜索似乎是第一次过滤,在我输入一些过滤字符串的意义上,列表得到更新,但是当我清除文本时我看不到正在显示的原始列表,我得到一个空列表。

2 个答案:

答案 0 :(得分:1)

  1. OrderManagerAdapter不应该扩展ArrayAdapter。你重写了足够多的方法,使得ArrayAdapter在很大程度上无关紧要。另外,你没有覆盖所有的mutate方法,这意味着如果你调用其中一个方法,你可能会遇到一些非常麻烦的麻烦。

  2. OrderManagerAdapter mutate方法都没有调用notifyDataSetChange。适配器在没有它们的情况下无法正常更新。

  3. 事实上,为什么甚至会覆盖ArrayAdapter,看起来你想要它提供的所有功能?您的OrderManagerAdapter根本没有正确完成,只会导致更多问题。您最好不要废弃OrderManagerAdapter并让ArticolAdapter扩展ArrayAdapter。

  4. 您的过滤器完全不正确:

    a)在后台线程上执行,并且所有列表修改周围都没有同步块。

    b)它完全更改了适配器的List引用,这意味着OrderManagerAdapter将不会指向与ArticolAdapter相同的数据列表,并且将来修改适配器的所有尝试都将失败。

    c)它还会使每个过滤器后的数据无效......这基本上意味着您的适配器已经死亡,不应该再报告任何数据更改

  5. 我不确定您的最终目标是什么,但如果只需要一个简单的方法来自定义ArrayAdapter的过滤结果,只需使用this guy即可。它可以为您节省大量的麻烦。

答案 1 :(得分:0)

在将数据重新分配给适配器后,您似乎没有使用 adapter.notifyDataSetChanged(); 刷新列表视图。首先更新你的dapter,然后调用adapter.notifyDataSetChanged();在你的活动中