1

Ich habe versucht, eine SearchView mit Vorschlägen (Filter) in Fragment zu implementieren, aber ich habe es nicht geschafft. Ich habe fast jedes Tutorial ausprobiert, aber nichts hat für mich funktioniert. Ich würde jede Hilfe schätzen. Vielen DankSearchView Filter mit 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" /> 

Fragment

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

Adapter

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

Dieses Tutorial ist sehr hilfreich für mich ... https: //www.learn2crack.com/2017/03/searchview-with-recyclerview.html – Chandan

Antwort

6

können Sie Klasse erstellen, die Filter

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

}

Und dann können Sie diesen Filter zu Ihrem ContactsAdapter hinzufügen.

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

vielen Dank! Also muss ich filterList auf OnQueryTextListener() aufrufen? –

+1

Ja, Sie können es in onQueryTextChange() aufrufen –

+0

OK, es funktioniert jetzt nicht, ich sehe es mir an. Noch eine Frage. Was genau macht das: für (endgültige Kontaktelement: contactList) { if (item.getName(). ToLowerCase(). Trim(). Enthält ("Muster")) { filteredContactList.add (Element); } } Ich meine .... enthält ("dieses Wort hier") –

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

Filterbare zu Ihrem Adapter Klasse implementieren

public class CategoryAdapter erweitert RecyclerView.Adapter implementiert Filterbare {

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

}