2012-08-07 16 views
5

Así que tengo un ArrayAdapter personalizado así que puedo usar la vista Título/Subtítulo que está disponible en el ListView. Tengo un EditText que acepta una cadena y filtra el adaptador.Android Custom ArrayAdapter no se actualiza después del filtro

El filtro funciona en el sentido de que se está filtrando los objetos correctos (que puedo decir haciendo clic sobre ella y comienza la intención con los "extras" correctas.)

Sin embargo a pesar de que las obras de filtrado, el los elementos del adaptador no se actualizan para mostrar la información correcta ... El título y los subtítulos son incorrectos.

Digamos que tenemos los elementos del 0 al 9 en el ListView, filtro a 3 elementos con una búsqueda, y digamos que los elementos filtrados son 5, 6, 9 ... Se muestran 3 elementos, pero son los 3 primeros elementos de la búsqueda previa original ListView (0-2). Si hago clic en el ítem 2 (el tercer ítem), el contenido de 9 está contenido en el nuevo intento. Esto es correcto para los criterios de búsqueda, sin embargo, el título reflejó la información correcta.

No estoy seguro de lo que necesito decirle al ListView para actualizar. No creo que sea notifyDataSetChanged();

Cualquier ayuda es apreciada. Gracias!

public class myListAdapter extends ArrayAdapter<Pizza>{ 
    private ArrayList<Pizza> items; 
    private PizzaViewHolder myListHolder; 

    private class PizzaViewHolder{ 
     TextView title; 
     TextView subtitle; 
    } 

    public myListAdapter(Context context, int textViewResourceId, ArrayList<Pizza> items) { 
     super(context, textViewResourceId, items); 
     this.items = items; 
     // TODO Auto-generated constructor stub 
    } 

    @Override 
    public View getView(int pos, View convertView, ViewGroup parent){ 
     View v = convertView; 
     if(v == null){ 
      LayoutInflater vi = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.myList_item, null); 
      myListHolder = new PizzaViewHolder(); 
      myListHolder.title = (TextView)v.findViewById(R.id.title); 
      myListHolder.subtitle = (TextView)v.findViewById(R.id.subtitle); 
      v.setTag(myListHolder); 
     }else myListHolder = (PizzaViewHolder)v.getTag(); 

     Pizza myList = items.get(pos); 

     if (myList != null){ 
      myListHolder.title.setText(myList.getTitle()); 
      myListHolder.subtitle.setText(myList.getSubTitle()); 
     }  
     return v;   
    } 
} 

Esta es la búsqueda

private TextWatcher filterTextWatcher = new TextWatcher(){ 

    public void afterTextChanged(Editable s) { 
     // TODO Auto-generated method stub 
     if(!s.equals("")){ 
      ((Filterable) this.listView1.getAdapter()).getFilter().filter(s); 
      } 
    } 

    public void beforeTextChanged(CharSequence s, int start, int count, 
      int after) { 
     // TODO Auto-generated method stub 

    } 

    public void onTextChanged(CharSequence s, int start, int before, 
      int count) { 
     // TODO Auto-generated method stub 

    } 

}; 
+0

El uso de un adaptador estándar funciona bien, no es necesario utilizar notifyDataSetChanged, mi adaptador personalizado no actualiza –

Respuesta

13

Por lo que he determinado, parece que necesitaba un filtro personalizado para mi ArrayAdapter personalizado. La costumbre ArrayAdapter tiene una implementación sustituida del filtro, aquí está el código:

import java.util.ArrayList; 
import android.content.Context; 
import android.util.Log; 
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 PizzaAdapter extends ArrayAdapter<Pizza>{ 

private ArrayList<Pizza> original; 
private ArrayList<Pizza> fitems; 
private Filter filter; 


public PizzaAdapter(Context context, int textViewResourceId, ArrayList<Pizza> items) { 
    super(context, textViewResourceId, items); 

    this.original = new ArrayList<Pizza>(items); 
    this.fitems = new ArrayList<Pizza>(items); 
    this.filter = new PizzaFilter(); 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent){ 
    View v = convertView; 

    if(v == null){ 
     LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.pizza_list_item, null); 
    } 

    Pizza pizza = fitems.get(position); 

    if(pizza != null){ 
     String subtitleString = new String("[" + pizza.getPizzaType() + "] " + pizza.getPizzaCategory() + ": " + pizza.getPizzaCode()); 

     TextView title = (TextView)v.findViewById(R.id.title); 
     TextView subtitle = (TextView)v.findViewById(R.id.subtitle); 

     if(title != null){ 
      title.setText(pizza.getPizzaName()); 
     } 
     if(subtitle != null){ 
      subtitle.setText(subtitleString); 
     } 
    } 
    return v; 
} 

@Override 
public Filter getFilter(){ 

    if(filter == null){ 
     filter = new PizzaFilter(); 
    } 
    return filter; 
} 

private class PizzaFilter extends Filter{ 
    @Override 
    protected FilterResults performFiltering(CharSequence constraint){ 
     FilterResults results = new FilterResults(); 
     String prefix = constraint.toString().toLowerCase(); 

     if (prefix == null || prefix.length() == 0){ 
      ArrayList<Pizza> list = new ArrayList<Pizza>(original); 
      results.values = list; 
      results.count = list.size(); 
     }else{ 
      final ArrayList<Pizza> list = new ArrayList<Pizza>(original); 
      final ArrayList<Pizza> nlist = new ArrayList<Pizza>(); 
      int count = list.size(); 

      for (int i = 0; i<count; i++){ 
       final Pizza pizza = list.get(i); 
       final String value = Pizza.getPizzaName().toLowerCase(); 

       if(value.contains(prefix)){ 
        nlist.add(pizza); 
       } 
       results.values = nlist; 
       results.count = nlist.size(); 
      } 
     } 
     return results; 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     fitems = (ArrayList<Pizza>)results.values; 
     notifyDataSetChanged(); 
     clear(); 
     int count = fitems.size(); 
     for(int i = 0; i<count; i++){ 
      add(fitems.get(i)); 
      notifyDataSetInvalidated(); 
     } 
    } 
} 
} 

Resulta que un implmentation costumbre de filtro actualiza la pantalla cuando buscado. Espero que esto ayude a algunas personas.

+3

uno de los mejores y más sencillos ejemplos en Internet. + – AlexAndro

+0

Cualquier idea de cómo puedo usar su código para resolver esto: http://stackoverflow.com/questions/20524417/listview-is-blank-while-using-getfilter-function – Si8

+0

'String prefix = constraint.toString(). toLowerCase(); 'puede lanzar' NullPointerException' – mallaudin

Cuestiones relacionadas