2010-10-20 6 views
3

Comme je voulais utiliser un adaptateur de liste personnalisé pour que je puisse styliser la liste mais la fonctionnalité de filtre ne fonctionne pas. J'ai le filtrage de base pour fonctionner, mais l'application se bloque dès que la liste des résultats filtrés est inférieure au nombre de listItems affichés lorsque je commence le filtrage.Android ArrayAdapter Problèmes de filtrage

Il y a aussi un deuxième problème que j'ai dans ce code que je ne suis pas sûr s'il est lié mais quand le clear(); s'exécute dans les publishResults, alors l'application se bloque également.

Voici le code que j'utilise.

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

}

Répondre

1

Essayez de changer votre méthode publishResults de la manière suivante:

@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

J'ai juste même problème. Mettez simplement la méthode getCount() dans votre classe d'adaptateur. Il devrait retourner le compte filtré. Quelque chose comme ceci:

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

Je filtre les périphériques.

Questions connexes