java – Android. Search and filter in recyclerview
Translate using "Google translate"!
Briefly describe the problem I decided to try recyclerview There is no need to implement all ready - made solutions such as search listview So I found a solution. If I need a solution at the bottom of the source code, there is a problem There is a list that shows the title when you click on any item in the second round of activiti that has a title and a complete description Realize that I like it: in mainactivity, I load from the database (using sugar ORM) header and ID
ArrayList<String> arrTitle = new ArrayList<>(); for(Contact contact:allContacts){ arrTitle.add(contact.title); } ArrayList<String> arrId = new ArrayList<>(); for(Contact contact:allContacts){ long i = contact.getId(); String str = Long.toString(i); arrId.add(str); }
They are then transferred to the adapter
mAdapter = new RecyclerAdapter(arrTitle,arrId);
Adapter recycler adapter I get the value, deduce the title to the list, and the second pass ID activity
@Override public void onBindViewHolder(ViewHolder holder,int position) { // Convert the id to the array idTab = new String[mId.size()]; for (int i = 0; i != mId.size(); i++) { idTab[i] = mId.get(i); } // Element position final int idvadaptere = position; // Display headers RecyclerView holder.mTextView.setText(mDataset.get(position)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Context context = v.getContext(); Intent ddddd = new Intent(context,LastActivity.class); ddddd.putExtra("id",idTab[idvadaptere]); context.startActivity(ddddd); } }); }
In the second activity lastactivity, I get the ID, and have inferred the value in the text field based on this ID
// Get the Intent extract from it an object // Extract from it an object idString = intent.getStringExtra("id"); // Convert the id in number idInt = Integer.parseInt(idString); // Display the text fields Contact title = Contact.findById(Contact.class,idInt); String titleStr = title.title; textView.setText(titleStr); Contact prich = Contact.findById(Contact.class,idInt); String prichStr = prich.prich; textView2.setText(prichStr);
The problem is that if a title is found, the title position of the list will not be the fifth. For example, the first and ID must be different from the second value. Aktiviti does not disclose the fifth ID, and the first Source search, if you need to copy anyone, it works normally. The only problem is to transfer data by clicking on the list item
activity_ main. In XML
<android.support.v7.widget.SearchView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/search_view" android:layout_gravity="right" app:theme="@style/Theme.AppCompat.NoActionBar" app:searchIcon="@drawable/ic_search_white_24dp"/>
MainActivity. java
private SearchView searchView;
In oncreate
searchView = (SearchView) findViewById(R.id.search_view); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String text) { return false; } @Override public boolean onQueryTextChange(String text) { mAdapter.filter(text); return false; } });
RecyclerAdapter. java
private ArrayList<String> mDataset; private ArrayList<String> mCleanCopyDataset;
Constructor
public RecyclerAdapter(ArrayList<String> dataset) { mDataset = dataset; mCleanCopyDataset = mDataset; }
search
// The filter () method we iterate through all the items on the list and if any item contains the search text,we add it to a new list mDataset: public void filter(String charText) { charText = charText.toLowerCase(Locale.getDefault()); mDataset = new ArrayList<String>(); if (charText.length() == 0) { // mCleanCopyDataset we always contains the unaltered and the filter (full) copy of the list of data mDataset.addAll(mCleanCopyDataset); } else { for (String item : mCleanCopyDataset) { // we iterate through all the items on the list and if any item contains the search text,we add it to a new list mDataset if (item.toLowerCase(Locale.getDefault()).contains(charText)) { mDataset.add(item); } } } // method notifyDataSetChanged () allows you to update the list on the screen after filtration notifyDataSetChanged(); }
Complete code recycleradapter java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> { private ArrayList<String> mDataset; private ArrayList<String> mId; private ArrayList<String> mCleanCopyDataset; String[] idTab; String[] titleTab; public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(View v) { super(v); mTextView = (TextView) v.findViewById(R.id.tv_recycler_item); } } public RecyclerAdapter(ArrayList<String> dataset,String[] titleTab,ArrayList<String> id) { mDataset = dataset; titleTab = titleTab; mId = id; mCleanCopyDataset = mDataset; } @Override public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.recycler_item,parent,false); ViewHolder vh = new ViewHolder(v); return vh; } @Override public void onBindViewHolder(final ViewHolder holder,int position) { idTab = new String[mId.size()]; for (int i = 0; i != mId.size(); i++) { idTab[i] = mId.get(i); } holder.mTextView.setText(mDataset.get(position)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Context context = v.getContext(); Intent ddddd = new Intent(context,LastActivity.class); ddddd.putExtra("id",idTab[holder.getAdapterPosition()]); context.startActivity(ddddd); } }); } @Override public int getItemCount() { return mDataset.size(); } public void filter(String charText) { charText = charText.toLowerCase(Locale.getDefault()); mDataset = new ArrayList<String>(); if (charText.length() == 0) { mDataset.addAll(mCleanCopyDataset); } else { for (String item : mCleanCopyDataset) { if (item.toLowerCase(Locale.getDefault()).contains(charText)) { mDataset.add(item); } } } notifyDataSetChanged(); }
}
Solution
You should use Android's built - in features to filter the recycle bin view
To do this, make your recycleradapter filterable
public class MyAdapter extends RecyclerVew.Adapter implements Filterable { private MyFilter filter; public MyAdapter() { // Do stuff } @Override public Filter getFilter() { if (filter == null) { filter = new MyFilter(this,getElements()); } return filter; }
You will notice that in this code example, I have something called myfilter This is what you will create and provide custom logic for
This is just an example
private static class MyFilter extends Filter { private final MyAdapter adapter; private final List<String> originalList; private final List<String> filteredList; private MyFilter(MyAdapter adapter,List<String> originalList) { super(); this.adapter = adapter; this.originalList = new LinkedList<>(originalList); this.filteredList = new ArrayList<>(); } @Override protected FilterResults performFiltering(CharSequence charSequence) { filteredList.clear(); final FilterResults results = new FilterResults(); if (charSequence.length() == 0) { filteredList.addAll(originalList); } else { final String filterPattern = charSequence.toString().toLowerCase().trim(); for (String item : originalList) { if (item.toLowerCase().contains(filterPattern) { filteredList.add(item); } } } results.values = filteredList; results.count = filteredList.size(); return results; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence charSequence,FilterResults filterResults) { mDataset.clear(); mDataset.add(filterResults.values); adapter.notifyDataSetChanged(); } }
Then, in your onQueryTextChange method, call the filter.
@Override public boolean onQueryTextChange(String text) { mAdapter.getFilter().filter(text); return false; }