1

Я попытался реализовать SearchView с предложениями (фильтрами) во Фрагменте, но я не справился с этим. Я пробовал почти каждый учебник, но ничего не работало для меня. Буду признателен за любую помощь. СпасибоФильтр SearchView с RecyclerView

XML ...

<!--appBar layout--> 
    <android.support.design.widget.AppBarLayout 
     android:id="@+id/appBarLayout" 
     android:fitsSystemWindows="true" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize"> 

     <!--searchView layout--> 
     <android.support.v7.widget.SearchView 
      android:id="@+id/search_view" 
      app:layout_scrollFlags="scroll|enterAlways" 
      android:iconifiedByDefault="false" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      app:closeIcon="@drawable/ic_clear_white_18dp" 
      app:searchIcon="@drawable/ic_search_white_24dp" 
      app:queryHint="@string/search_contact" 
      app:iconifiedByDefault="false" 
      android:background="@color/colorPrimary" 
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" /> 

     </android.support.design.widget.AppBarLayout> 

     <!-- recycler view--> 
     <android.support.v7.widget.RecyclerView 
      app:layout_behavior="@string/appbar_scrolling_view_behavior" 
      android:id="@+id/recycler_view" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" /> 

Фрагмент

@Override 
    public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_contact_list, container, false); 

     searchView = (SearchView)view.findViewById(R.id.search_view); 
     fabButton = (FloatingActionButton)view.findViewById(R.id.fab_button); 

     //recycler view 
     recyclerView = (RecyclerView)view.findViewById(R.id.recycler_view); 
     recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 
     contacts = SugarRecord.listAll(Contact.class); 
     contactsAdapter = new ContactsAdapter(getActivity(), contacts); 
     recyclerView.setAdapter(contactsAdapter); 

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

      @Override 
      public boolean onQueryTextChange(String newText) { 
       // TODO: setFilter 

       return true; 
      } 
     }); 

     return view; 

адаптер

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactVH> { 

    List<Contact> mContact; 
    List<Contact> mContactFilter; 

    Context mContext; 

    public ContactsAdapter(Context context, List<Contact> contact) { 
     this.mContact = contact; 
     this.mContext = context; 
    } 

    @Override 
    public ContactVH onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_contact, parent, false); 
     ContactVH viewHolder = new ContactVH(view); 
     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(ContactVH holder, int position) { 
     holder.name.setText(mContact.get(position).getName()); 
    } 

    @Override 
    public int getItemCount() { 
     return mContact.size(); 
    } 

    class ContactVH extends RecyclerView.ViewHolder { 
     @BindView(R.id.contact_name) 
     TextView name; 

     public ContactVH(View itemView) { 
      super(itemView); 
      ButterKnife.bind(this, itemView); 
     } 

    } 

} 
+0

Этот учебник очень полезно для меня ... https: //www.learn2crack.com/2017/03/searchview-with-recyclerview.html – Chandan

ответ

6

Вы можете создать класс, который расширяет фильтр

class YourFilterClass extends Filter { 

private List<Contact> contactList; 
private List<Contact> filteredContactList; 
private ContactsAdapter adapter; 

    public YourFilterClass(List<Contact> contactList, ContactsAdapter adapter) { 
    this.adapter = adapter; 
    this.contactList = contactList; 
    this.filteredContactList = new ArrayList(); 
    } 

    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
    filteredContactList.clear(); 
    final FilterResults results = new FilterResults(); 

    //here you need to add proper items do filteredContactList 
    for (final Contact item : contactList) { 
      if (item.getName().toLowerCase().trim().contains("pattern")) { 
       filteredContactList.add(item); 
      } 
     } 

     results.values = filteredContactList; 
     results.count = filteredContactList.size(); 
     return results; 
    } 

    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     adapter.setList(filteredContactList); 
     adapter.notifyDataSetChanged(); 
    } 

}

И тогда вы можете добавить этот фильтр к вашему ContactsAdapter.

public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.ContactVH> { 

List<Contact> mContact; 
List<Contact> mContactFilter; 
YourFilterClass filter; 

Context mContext; 

public ContactsAdapter(Context context, List<Contact> contact) { 
    this.mContact = contact; 
    this.mContactFilter = contact; 
    this.mContext = context; 
    filter = new YourFilterClass(mContact, this); 
} 

@Override 
public ContactVH onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_contact, parent, false); 
    ContactVH viewHolder = new ContactVH(view); 
    return viewHolder; 
} 

@Override 
public void onBindViewHolder(ContactVH holder, int position) { 
    holder.name.setText(mContactFilter.get(position).getName()); 
} 
// set adapter filtered list 
public void setList(List<Contact> list) { 
    this.mContactFilter = list; 
} 
//call when you want to filter 
public void filterList(String text) { 
    filter.filter(text); 
} 

@Override 
public int getItemCount() { 
    return mContactFilter.size(); 
} 

class ContactVH extends RecyclerView.ViewHolder { 
    @BindView(R.id.contact_name) 
    TextView name; 

    public ContactVH(View itemView) { 
     super(itemView); 
     ButterKnife.bind(this, itemView); 
    } 

} 

}

+0

Спасибо большое! Поэтому мне нужно вызвать filterList на OnQueryTextListener()? –

+1

Да вы можете называть его inQueryTextChange() –

+0

ОК, теперь это не работает, я смотрю на него. Еще один вопрос. Что именно это делает: для (конечный контактный элемент: контактный лист) { if (item.getName(). ToLowerCase(). Trim(). Содержит ("шаблон")) { отфильтрованныйContactList.add (item); } } Я имею в виду .... содержит («это слово здесь») –

0

Try This

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 

    inflater.inflate(R.menu.main_menu, menu); 

    MenuItem mSearchMenuItem = menu.findItem(R.id.search); 
    SearchView searchView = (SearchView) mSearchMenuItem.getActionView(); 

    search(searchView); 
} 

public static void search(android.support.v7.widget.SearchView searchView) { 

    searchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() { 
     @Override 
     public boolean onQueryTextSubmit(String query) { 

      return false; 
     } 

     @Override 
     public boolean onQueryTextChange(String newText) { 
      mCategoryAdapter.getFilter().filter(newText); 
      return true; 
     } 
    }); 
} 

реализовать Фильтруемый к классу адаптер

общественного класса CategoryAdapter расширяет RecyclerView.Adapter реализует фильтруемых {

private List<Category> categoryList; 
private List<Category> mFilteredList; 


public CategoryAdapter(List<Category> categoryList) { 

    this.categoryList = categoryList; 
    this.mFilteredList = categoryList; 
} 

@Override 
public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View itemView = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.category_card, parent, false); 

    return new CategoryViewHolder(itemView); 
} 

@Override 
public void onBindViewHolder(CategoryViewHolder holder, int position) { 
     Category category = mFilteredList.get(position); 
     holder.catname.setText(category.getCatName()); 
     holder.items.setText(category.getCatItems()+" Items"); 


} 

@Override 
public int getItemCount() { 
    return mFilteredList.size(); 
} 

@Override 
public Filter getFilter() { 
    return new Filter() { 
     @Override 
     protected FilterResults performFiltering(CharSequence charSequence) { 

      String charString = charSequence.toString(); 
      if (charString.isEmpty()) { 

       mFilteredList = categoryList; 
      } else { 

       List<Category> filteredList = new ArrayList<>(); 

       for (Category category : categoryList) { 

        if (category.getCatName().toLowerCase().contains(charString) || String.valueOf(category.getId()).contains(charString)) { 

         filteredList.add(category); 
        } 
       } 

       mFilteredList = filteredList; 
      } 

      FilterResults filterResults = new FilterResults(); 
      filterResults.values = mFilteredList; 
      return filterResults; 
     } 

     @Override 
     protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 
      mFilteredList = (List<Category>) filterResults.values; 
      notifyDataSetChanged(); 
     } 
    }; 
} 

public class CategoryViewHolder extends RecyclerView.ViewHolder { 
    public TextView catname, items; 
    public ImageView imgView; 

    public CategoryViewHolder(View view) { 
     super(view); 
     catname = view.findViewById(R.id.categorycard_cate_name); 
     items = view.findViewById(R.id.categorycard_lbl_cat_items); 

    } 
} 

public void removeItem(int position) { 
    mFilteredList.remove(position); 
    // notify the item removed by position 
    // to perform recycler view delete animations 
    // NOTE: don't call notifyDataSetChanged() 
    notifyItemRemoved(position); 
} 

public void restoreItem(Category category, int position) { 
    mFilteredList.add(position, category); 
    // notify item added by position 
    notifyItemInserted(position); 
} 

}

Смежные вопросы