Android ArrayAdapter Фильтрация проблем - PullRequest
3 голосов
/ 20 октября 2010

Поскольку я хотел использовать пользовательский адаптер списка, чтобы я мог стилизовать список, но функция фильтра не работает.Я получил базовую фильтрацию для работы, но приложение вылетает, как только список отфильтрованных результатов становится меньше числа listItems, показанного при запуске фильтрации.

Есть также вторая проблема, с которой я столкнулся в этом кодечто я не уверен, что это связано, но когда 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 ]

2 голосов
/ 31 октября 2012

У меня просто такая же проблема. Просто поместите метод getCount () в свой класс адаптера. Должен вернуть отфильтрованный счетчик. Примерно так:

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

Я фильтрую элементы.

1 голос
/ 31 октября 2012

Попробуйте изменить метод 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();
        }

        }
...