2010-10-20 71 views
3

正如我想使用自定義列表適配器,以便我可以風格列表,但過濾器功能無法正常工作。我得到了基本的過濾工作,但是隻要過濾結果列表少於我開始過濾時顯示的listItem數量,應用程序就會崩潰。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(); 
} 

我過濾了mItems。