2012-08-07 15 views
5

So habe ich eine benutzerdefinierte ArrayAdapter so kann ich den Titel/Untertitel Ansicht verwenden, die auf dem ListView zur Verfügung steht. Ich habe eine EditText, die einen String und filtert den Adapter übernimmt.Android Individuelle ArrayAdapter nicht aktualisiert, nachdem Filter

Der Filter im Sinne wirkt, dass es die richtigen Objekte filtert (ich kann es durch Klicken sagen, und es beginnt die Absicht mit den richtigen „Extras“).

Jedoch obwohl die Filter Werke, die Elemente im Adapter werden nicht aktualisiert, um die korrekten Informationen anzuzeigen ... Der Titel und der Untertitel sind falsch.

Sagen wir, wir haben Artikel 0 bis 9 auf der ListView, ich filter auf 3 Elemente mit einer Suche und lässt sagen, die gefilterten Elemente sind 5, 6, 9 ... 3 Elemente angezeigt werden, aber es ist die erste 3 Elemente der ursprünglich vorge Suche ListView (0-2). Wenn ich auf den Punkt 2 (der dritte Punkt) klicke, sind die Inhalte von 9 in der neuen Absicht enthalten. Dies ist korrekt für die Suchkriterien, der Titel hat jedoch die richtige Information wiedergegeben.

Ich bin nicht sicher, was ich die ListView auffrischen zu sagen brauchen. Ich glaube nicht, dass es notifyDataSetChanged();

Jede Hilfe wird geschätzt. Danke!

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

Dies ist die Suche

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

einen Standard-Adapter funktioniert gut, keine Notwendigkeit notifyDataSetChanged zu verwenden, meine benutzerdefinierte Adapter nicht aktualisiert –

Antwort

13

Von dem, was ich bestimmt haben, es scheint, dass ich einen benutzerdefinierten Filter für meine benutzerdefinierten ArrayAdapter benötigt. Der Brauch ArrayAdapter hat eine überschriebene Implementierung von Filtern, hier ist der Code:

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

Es stellt sich heraus, dass eine benutzerdefinierte implmentation der Filter die Anzeige aktualisiert, wenn Sie gesucht haben. Hoffentlich wird dies einigen Menschen helfen.

+3

einer der besten und einfachsten Beispiel über das Internet. + – AlexAndro

+0

Jede Idee, wie ich Ihren Code verwenden kann, um dies zu beheben: http://stackoverflow.com/questions/20524417/listview-is-blank-while-using-getfilter-function – Si8

+0

'String prefix = constraint.toString(). toLowerCase(); 'kann' NullPointerException' werfen – mallaudin

Verwandte Themen