2010-10-20 2 views
3

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

Существует также вторая проблема, которая возникает у меня в этом коде, что я не уверен, если это связано, но когда 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(); 
    } 
} 

}

ответ

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

     } 
2

Я просто такая же проблема. Просто поместите метод getCount() в свой класс адаптера. Он должен возвращать отфильтрованный подсчет. Что-то вроде этого:

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

I фильтр mItems.

Смежные вопросы