2012-08-07 118 views
5

所以我有一个自定义ArrayAdapter,所以我可以使用ListView上可用的标题/字幕视图。我有一个接受字符串并过滤适配器的EditTextAndroid自定义ArrayAdapter不会刷新后过滤器

过滤器工作在某种意义上说,它是过滤了正确的对象(我可以通过点击它告诉我们,它开始用正确的“额外”的意图。)

然而,即使过滤工程,适配器中的项目不会更新以显示正确的信息...标题和副标题不正确。我们可以假设我们在ListView上有0到9的项目,我用搜索过滤到3个项目,并且可以说过滤的项目是显示的5,6,9 ... 3项目,但是它的前3个项目原始预搜索项目ListView(0-2)。如果我点击项目2(第三项),则9的内容将包含在新的意图中。这对于搜索条件是正确的,但标题确实反映了正确的信息。

我不知道我需要告诉ListView刷新。 我不认为它notifyDataSetChanged();

任何帮助表示赞赏。 谢谢!

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

这是搜索

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

使用标准适配器工作正常,不需要使用notifyDataSetChanged,我的自定义适配器不会刷新 – 2012-08-07 17:53:18

回答

13

从我已经确定的东西,看来我需要为我定制ArrayAdapter自定义过滤器。 自定义ArrayAdapter有一个强制执行过滤器的,这里是代码:

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

事实证明,当你搜索过滤器的定制implmentation更新显示。希望这会帮助一些人。

+3

在互联网上最好和最简单的例子之一。 + – AlexAndro 2013-06-21 13:35:39

+0

任何想法如何我可以使用您的代码来解决这个问题:http://stackoverflow.com/questions/20524417/listview-is-blank-while-using-getfilter-function – Si8 2013-12-13 22:07:47

+0

'字符串前缀= constraint.toString()。 toLowerCase();'可以抛出'NullPointerException' – mallaudin 2017-03-30 06:50:33