Android ArrayAdapter过滤问题

时间:2010-10-20 18:02:50

标签: android listview filter android-arrayadapter

因为我想使用自定义列表适配器,所以我可以设置列表样式,但过滤器功能不起作用。我得到了基本的过滤功能,但是一旦过滤结果列表小于我开始过滤时显示的listItem数量,应用程序就会崩溃。

我在这段代码中还遇到了第二个问题,我不确定它是否相关但是当时 clear();在publishResults中运行,然后应用程序也崩溃。

这是我正在使用的代码。

package com.android.example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

public class CustomListAdapter extends ArrayAdapter<String> {
    private Context mContext; 
private String[] items;
private String[] filtered;

public CustomListAdapter(Context context, int textViewResourceId, String[] items) {
        super(context, textViewResourceId, items);
        this.filtered = items;
        this.items = filtered;

        setNotifyOnChange(true);
        mContext = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     View v = convertView;
     if (v == null) {
         LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         v = vi.inflate(R.layout.list_item, null);
     }
     String o = filtered[position];
     if (o != null) {
             TextView tt = (TextView) v.findViewById(R.id.tvViewRow);
             if (tt != null) {
                   tt.setText("Name: "+o);
             }
     }
     return v;
}

public void notifyDataSetInvalidated()
{
    super.notifyDataSetInvalidated();
}


private Filter filter;


public Filter getFilter()
{
    if(filter == null)
        filter = new NameFilter();
    return filter;
}
private class NameFilter extends Filter
{
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        // NOTE: this function is *always* called from a background thread, and
        // not the UI thread.
        constraint = constraint.toString().toLowerCase();
        FilterResults result = new FilterResults();
        if(constraint != null && constraint.toString().length() > 0)
        {
            ArrayList<String> filt = new ArrayList<String>();
            List<String> lItems = new ArrayList<String>();
            synchronized (items)
            {     
                lItems = Arrays.asList(items);  
                //Collections.copy(lItems, Arrays.asList(items));
            }
            for(int i = 0, l = lItems.size(); i < l; i++)
            {
                String m = lItems.get(i);
                if(m.toLowerCase().startsWith(constraint.toString()))
                    filt.add(m);
            }
            result.count = filt.size();
            result.values = filt.toArray(new String[0]);
        }
        else
        {
            synchronized(items)
            {
                result.values = items;
                result.count = Arrays.asList(items).size();
            }
        }
        return result;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        // NOTE: this function is *always* called from the UI thread.

            filtered = (String[])results.values;
            notifyDataSetChanged();
            clear();
            notifyDataSetInvalidated();
    }
}

}

2 个答案:

答案 0 :(得分:2)

我有同样的问题。只需将getCount()方法放在适配器类中。它应该返回过滤计数。像这样:

public int getCount() {
    return mItems.size();  
}

我过滤了mItems。

答案 1 :(得分:1)

尝试以下列方式更改publishResults方法:

 @Override
        public void publishResults(CharSequence constraint, FilterResults results) {

            List<T> filtered = (ArrayList<T>) results.values;
            adapter.notifyDataSetChanged();
            adapter.clear();
            if (filtered != null) {

            for (int i = 0; i < filtered.size(); i++)
                adapter.add(filtered.get(i));
            }
            adapter.notifyDataSetInvalidated();
        }

        }