views:

10

answers:

0

While working on this app, I wanted to use a Custom List Adapter so that I could style the list but the Filter functionality is not working. I got the basic filtering to work but the application crashes as soon as the list of filtered results is less than the number of listItems shown when I start filtering.

There is also a second problem I am having in this code that I am not sure if it is related but when the clear(); gets run in the publishResults, then the application also crashes.

Here is the code I am using.

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

}