2014-12-23 78 views
0

我很难找到这个好的教程。我有一个ListView,我想添加一个'搜索'功能,根据用户在操作栏中找到的搜索小部件的输入过滤列表视图。ListView搜索部件过滤器

我已经浏览了一些教程和几篇文章,但无法围绕这个概念包裹我的头。我最近的努力是根据this site

以下是我的自定义适配器代码(请注意,它可能有不必要的代码,由于我在得到它的工作的尝试:

package adapters; 

import android.app.Activity; 
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.Filterable; 
import android.widget.TextView; 

import com.example.khalid.hisnulmuslim.R; 

import java.util.ArrayList; 
import java.util.List; 

import classes.Dua; 

public class DuaGroupAdapter extends ArrayAdapter<Dua> implements Filterable { 

    /* Filterable things */ 
    private List<Dua> allModelItemsArray; 
    private List<Dua> filteredModelItemsArray; 
    private Activity context; 
    private ModelFilter filter; 
    private LayoutInflater inflator; 

    public DuaGroupAdapter(Activity context, List<Dua> list) { 
     super(context, R.layout.dua_list_item_card, list); 
     this.context = context; 
     this.allModelItemsArray = new ArrayList<Dua>(); 
     allModelItemsArray.addAll(list); 
     this.filteredModelItemsArray = new ArrayList<Dua>(); 
     filteredModelItemsArray.addAll(allModelItemsArray); 
     inflator = context.getLayoutInflater(); 
     getFilter(); 
    } 
    /* End of Filterable things */ 

    public DuaGroupAdapter(Context context, int textViewResourceId) { 
     super(context, textViewResourceId); 
    } 

    public DuaGroupAdapter(Context context, int resource, List<Dua> items) { 
     super(context, resource, items); 
    } 

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

     if (v == null) { 
      LayoutInflater vi; 
      vi = LayoutInflater.from(getContext()); 
      v = vi.inflate(R.layout.dua_list_item_card, null); 
     } 

     Dua p = getItem(position); 

     if (p != null) { 
      TextView tvReference = (TextView) v.findViewById(R.id.txtReference); 
      TextView tvDuaName = (TextView) v.findViewById(R.id.txtDuaName); 

      if (tvReference != null) { 
       tvReference.setText("" + p.getReference()); 
      } 
      if (tvDuaName != null) { 
       tvDuaName.setText(p.getTitle()); 
      } 
     } 
     return v; 
    } 

    private class ModelFilter extends Filter { 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 

      constraint = constraint.toString().toLowerCase(); 
      FilterResults result = new FilterResults(); 
      if (constraint != null && constraint.toString().length() > 0) { 
       ArrayList<Dua> filteredItems = new ArrayList<Dua>(); 

       for (int i = 0, l = allModelItemsArray.size(); i < l; i++) { 
        Dua m = allModelItemsArray.get(i); 
        if (m.getGroup().toLowerCase().contains(constraint)) 
         filteredItems.add(m); 
       } 
       result.count = filteredItems.size(); 
       result.values = filteredItems; 
      } else { 
       synchronized (this) { 
        result.values = allModelItemsArray; 
        result.count = allModelItemsArray.size(); 
       } 
      } 
      return result; 
     } 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 

      filteredModelItemsArray = (ArrayList<Dua>) results.values; 
      notifyDataSetChanged(); 
      clear(); 
      for (int i = 0, l = filteredModelItemsArray.size(); i < l; i++) 
       add(filteredModelItemsArray.get(i)); 
      notifyDataSetInvalidated(); 
     } 
    } 
} 

这是我的布局XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <ListView 
     android:id="@+id/duaListView" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:clipToPadding="false" 
     android:background="@android:color/white"/> 
</RelativeLayout> 

的过滤器所需的文本将从操作栏中的搜索小部件中获得,该活动能够检测何时将文本输入到搜索小部件文本字段中,但它什么都不显示; listView空白,它返回原始一旦所有文本被删除,状态为

ListView中的各行不只有两个textViews那么复杂如下面给出

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" 
    android:padding="15dp" 
    android:background="?android:attr/selectableItemBackground"> 

    <TextView 
     android:id="@+id/txtReference" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:fontFamily="sans-serif-condensed" 
     android:text="1" 
     android:textStyle="bold" /> 

    <View 
     android:layout_width="15dp" 
     android:layout_height="fill_parent" /> 

    <TextView 
     android:id="@+id/txtDuaName" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:fontFamily="sans-serif-light" 
     android:text="Entering the Bathroom" /> 
</LinearLayout> 

是否有人可以帮助我吗?谢谢你的时间。

+0

你有没有调试过你的任何循环来找出这些数组是否被填充?你的getItem和添加方法在哪里?另外,我相信你可能会将你的notifyDataSetChanged和notifyDataSetInvalidated调用翻转过来,在为你的适配器设置数据之后应该调用它 – Shooky

回答

0

的朋友帮忙解决了这个功能。下面是建立一个过滤器的重要片段:

public class DuaGroupAdapter extends BaseAdapter implements Filterable { 
    private Context mContext; 
    private LayoutInflater mInflater; 
    private List<Dua> mList;  

    @Override 
    public Filter getFilter() { 
     // return a filter that filters data based on a constraint 
     return new Filter() { 
      @Override 
      protected FilterResults performFiltering(CharSequence constraint) { 
       final ExternalDbOpenHelper helper = ExternalDbOpenHelper.getInstance(mContext); 
       final SQLiteDatabase db = helper.openDataBase(); 

       final List<Dua> duas = new ArrayList<>(); 
       Cursor c = null; 
       try { 
        c = db.query(HisnDatabaseInfo.DuaGroupTable.TABLE_NAME, null, 
          HisnDatabaseInfo.DuaGroupTable.ENGLISH_TITLE + " like ?", 
          new String[] { "%" + constraint + "%" }, null, null, null); 
        if (c != null && c.moveToFirst()) { 
         do { 
          final Dua dua = new Dua(c.getInt(0), c.getString(2)); 
          duas.add(dua); 
         } while (c.moveToNext()); 
        } 
       } finally { 
        if (c != null) { 
         c.close(); 
        } 
       } 

       final FilterResults results = new FilterResults(); 
       results.values = duas; 
       results.count = duas.size(); 
       return results; 
      } 

      @Override 
      protected void publishResults(CharSequence constraint, Filter.FilterResults results) { 
       if (results.count > 0) { 
        mList = (List<Dua>) results.values; 
        notifyDataSetChanged(); 
       } else { 
        notifyDataSetInvalidated(); 
       } 
      } 
     }; 
    } 

适配器的完整的代码可以发现here。感谢所有的答复。

0
  1. 您链接的那个网站是3岁,完全不正确,并且是一个可怕的例子。忘记它甚至存在。
  2. 如果您需要自定义实施过滤逻辑,请不要扩展ArrayAdapter。尝试这样做时会遇到种种问题。要包括同步问题,无法保持列表和内部适配器列表同步等。有关更多信息,请参阅:Filtering Problems

当您需要过滤的自定义解决方案时,有两种选择。

  1. 从零开始编写您自己的适配器...例如,扩展BaseAdapter
  2. 使用第三方库。特别是专门设计用来做你刚才所要求的东西。
0

它可以帮助你,

在片段

searchView.setOnQueryTextListener(new OnQueryTextListener() 
{ 
    @Override 
    public boolean onQueryTextSubmit(String query) 
    { 
     return false; 
    } 

    @Override 
    public boolean onQueryTextChange(String newText) 
    { 
     mSearchStr = newText; 
     if(mSearchStr.isEmpty()) 
     { 
      mContList = new ArrayList<HashMap<String, String>>(); 
      FetchContacts(); 
     } 
     else if(mSearchStr.length()>=1) 
     { 
      mMyListAdapter.getFilter().filter(mSearchStr.toString()); 
     } 
     return true; 
    } 
}); 

在adapter.class

package com.example.samplephonecontact; 

    import java.util.ArrayList; 
    import java.util.HashMap;  
    import com.example.samplephonecontact.ContactListFragment; 
    import android.annotation.SuppressLint; 
    import android.content.Context; 
    import android.graphics.Bitmap; 
    import android.view.LayoutInflater; 
    import android.view.View; 
    import android.view.ViewGroup; 
    import android.widget.BaseAdapter; 
    import android.widget.Filter; 
    import android.widget.Filterable; 
    import android.widget.ImageView; 
    import android.widget.TextView; 

    public class ContactListAdapter extends BaseAdapter implements Filterable 
    { 
     private Context mContext; 
     private ValueFilter mValueFilter; 
     ArrayList<HashMap<String, String>> mContList; 
     ArrayList<HashMap<String, String>> mFilteredContList; 
     HashMap<String, String> mContObj ; 

     public ContactListAdapter(Context context, ArrayList<HashMap<String, String>> PackageList) 
     { 
       this.mContext = context; 
       this.mContList = PackageList; 
       this.mFilteredContList = PackageList; 
     } 

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

     public Object getItem(int position) 
     { 
      return mContList.get(position); 
     } 

     public long getItemId(int position) 
     { 
      return position; 
     } 

     public View getView(int position, View convertView, ViewGroup viewGroup) 
     {  
      LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = mInflater.inflate(R.layout.cont_list, null); 

      TextView contactName = (TextView) convertView.findViewById(R.id.name); 
      TextView contactNumber = (TextView) convertView.findViewById(R.id.number); 
      ImageView contactImage = (ImageView) convertView.findViewById(R.id.contactimage); 
      mContObj = new HashMap<String, String>(); 
      mContObj = mContList.get(position); 
      String name = mContObj.get("name"); 
      String number = mContObj.get("number"); 
      contactName.setText(name); 
      contactNumber.setText("\t"+number); 

      int resid = R.drawable.person1; 
      contactImage.setImageResource(resid); 

      return convertView; 
     } 
     @Override 
     public Filter getFilter() 
     { 
      if(mValueFilter==null) 
      { 
       mValueFilter=new ValueFilter(); 
      } 
       return mValueFilter; 
     } 

     private class ValueFilter extends Filter 
     { 
      @SuppressLint("DefaultLocale") 
      @Override 
      protected FilterResults performFiltering(CharSequence constraint) 
      { 
       FilterResults results=new FilterResults(); 
       ArrayList<HashMap<String, String>> filterList=new ArrayList<HashMap<String,String>>(); 
       if(constraint!=null && constraint.length()>0) 
       { 
        for(int i=0;i<mFilteredContList.size();i++) 
        { 
         if((mFilteredContList.get(i).get("name").toString().toUpperCase()).contains(constraint.toString().toUpperCase())) 
         { 
          String name = mFilteredContList.get(i).get("name"); 
          String num = mFilteredContList.get(i).get("number"); 
          String id= mFilteredContList.get(i).get("id"); 
          String numType = mFilteredContList.get(i).get("number_type"); 
          String mail = mFilteredContList.get(i).get("mail"); 
          String mailtype = mFilteredContList.get(i).get("mail_type"); 
          String ch = constraint.toString().toUpperCase(); 
          if(name.toUpperCase().contains(ch)) 
          { 
           HashMap<String, String> list = new HashMap<String, String>(); 
           list.put("id", id); 
           list.put("name", name); 
           list.put("number", num); 
           list.put("number_type", numType); 
           list.put("mail", mail); 
           list.put("mail_type", mailtype); 
           filterList.add(list); 
          } 
         } 
        } 
        results.count=filterList.size(); 
        results.values=filterList; 
        ArrayItem ai = new ArrayItem(); 
        ai.setMyArrayList(filterList); 
       } 
       else 
       { 
        results.count=mFilteredContList.size(); 
        results.values=mFilteredContList; 
       } 
       return results; 
      } 

      @SuppressWarnings("unchecked") 
      @Override 
      protected void publishResults(CharSequence constraint, FilterResults results) 
      { 
       mContList=(ArrayList<HashMap<String,String>>) results.values; 
       notifyDataSetChanged(); 
      } 
     } 
    }