Панель инструментов с временной фильтрацией SearchView RecyclerView
Мне нужно реализовать функцию поиска внутри моего приложения для Android, которое использует панель инструментов, SlidingTabLayout и ViewPager, которая содержит фрагменты. Внутри каждого фрагмента есть RecyclerView со списком элементов.
Данные RecyclerView статичны в отдельном классе (DataAccess.java), и эти списки обновляются, а RecyclerView обновляется только путем вызова (без передачи новых данных).
mRecyclerView.getAdapter().notifyDataSetChanged();
Есть ли простой способ временного фильтра RecyclerView без изменения данных и после того, как пользователь нажимает кнопку возврата на панели инструментов, чтобы удалить фильтр и показать список в списке.
Перед тем, как нажать значок поиска внутри меню панели инструментов:
![enter image description here]()
Итак, когда пользователь вводит "Josip...", фильтр будет активным
![enter image description here]()
и после нажатия кнопки X в SearchView пользователь получит те же данные, что и раньше, без фильтра.
@Override
public boolean onQueryTextChange(String newText) {
// filter data (temporary remove all items from DataAccess.list that don't .startsWith(newText)
}
@Override
public boolean onQueryTextSubmit(String query)
// Doesn't help if I revert deleted items here
}
Ответы
Ответ 1
@Override
public boolean onQueryTextSubmit(String query){
((ItemAdapter) myRecList.getAdapter()).setFilter(query)
}
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
private List<String> visibleObjects;
private List<String> allObjects;
.....
public void flushFilter(){
visibleObjects=new ArrayList<>();
visibleObjects.addAll(allObjects);
notifyDataSetChanged();
}
public void setFilter(String queryText) {
visibleObjects = new ArrayList<>();
constraint = constraint.toString().toLowerCase();
for (String item: allObjects) {
if (item.toLowerCase().contains(queryText))
visibleObjects.add(item);
}
notifyDataSetChanged();
}
}
Ответ 2
Я хотел добавить комментарий, но из-за меньшей репутации... Я отвечаю на пост.
Этот метод отлично работает, если (item.toLowerCase(). Содержит (queryText)), но что делать, если совпадение не найдено в первой итерации. Затем он будет входить иначе, не зацикливаясь в списке allObjects...
for (RouteByATMList.Route_ATM item: Main_ATMItemList)
{
if (item.ATMNumber.contains(queryText)) {
visibleObjects.add(item);
}else {
Toast.makeText(mContext,"No search result found!",Toast.LENGTH_SHORT).show();
break;
}
}
Я получил ответ от своего начальника, надеюсь, что это поможет.
public void setFilter(String queryText) {
visibleObjects = new ArrayList<>();
for (RouteByATMList.Route_ATM item: Main_ATMItemList)
{
if (item.ATMNumber.contains(queryText))
{
visibleObjects.add(item);
}
}
if(visibleObjects.size()==0){
Toast.makeText(mContext,"No search result found!",Toast.LENGTH_SHORT).show();
}
notifyDataSetChanged();
Log.e("dataset changed","dataset changed");
}
Ответ 3
Я не возражаю против данного и принятого ответа. Есть место для возможных ошибок производительности. Нужно использовать интерфейс Filterabe
. Внедрение этого будет вести себя как ol'good ListView
, который сделал асинхронную фильтрацию. Тогда вам нужно написать свой собственный Filter
и создать экземпляр в переопределенном методе getFilter()
;
В моем случае я использовал Filter
для сортировки адаптера многих (да, многих) элементов. Это был junky, сортирующий его на UI-нитке.
Итак, у меня был этот абстрактный класс
public abstract class BaseFilterableRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements Filterable {
private Context mContext;
public BaseFilterableRecyclerViewAdapter(Context context) {
this.mContext = context;
}
public abstract void sort(SortingFilter.Sort sortingStrategy);
//...Other methods
}
И класс, который наследует:
public class ItemAdapter extends BaseFilterableRecyclerViewAdapter<RecyclerView.ViewHolder>{
//... RecyclerView methods
@Override
public Filter getFilter() {
return new SortingFilter(mData) {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.values != null) {
int last = mData.size();
mData = (List<Product>) results.values;
notifyDataSetChanged();
}
}
};
}
@Override
public void sort(SortingFilter.Sort sortingStrategy) {
getFilter().filter(sortingStrategy.toString());
}
}