12

Tôi cần triển khai chức năng tìm kiếm bên trong ứng dụng Android sử dụng thanh công cụ, SlidingTabLayout và ViewPager chứa các đoạn. Bên trong mỗi đoạn có một RecyclerView với danh sách các mục.Thanh công cụ với bộ lọc tạm thời SearchView RecyclerView

dữ liệu RecyclerView được tĩnh được định nghĩa trong lớp riêng biệt (DataAccess.java) và những danh sách được cập nhật và RecyclerView được làm mới chỉ bằng cách gọi (không thông qua dữ liệu mới)

mRecyclerView.getAdapter().notifyDataSetChanged(); 

Có cách nào đơn giản để lọc tạm thời RecyclerView mà không thay đổi dữ liệu và sau khi người dùng nhấn nút quay lại bên trong Thanh công cụ để xóa bộ lọc và hiển thị danh sách inital.

Trước khi nhấn vào biểu tượng Tìm kiếm bên trong thanh thực đơn:

enter image description here

Vì vậy, khi người dùng gõ "Josip ..." bộ lọc sẽ được kích hoạt

enter image description here

và sau khi ông nhấn nút X trong SearchView người dùng sẽ nhận được dữ liệu giống như trước đây mà không có bộ lọc.

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

Trả lời

23
@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(); 
    } 
} 
+0

Cảm ơn câu trả lời của người đàn ông !! Tôi nên gọi flushFilter() ở đâu? – fpopic

+1

IN @Override boolean công khai trênQueryTextChange (String newText) { if (text.isEmpty()) ((ItemAdapter) myRecList.getAdapter) .flushFilter(); } HOẶC IN OnActionExpandListener.onMenuItemActionCollapse (MenuItem item) – merovingen

+0

searchView.setOnCloseListener() là điều, cảm ơn dù bình luận của bạn đã đưa tôi đi đúng hướng! – fpopic

3

tôi muốn thêm như bình luận nhưng do danh tiếng ít ... tôi trả lời bài. Phương pháp này hoạt động tốt nếu (item.toLowerCase() chứa (queryText)) nhưng phải làm gì nếu kết hợp không được tìm thấy trong lần lặp đầu tiên.nó nó sẽ đi vào phần khác mà không lặp trong danh sách 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; 
      } 
     } 

Tôi nhận được câu trả lời từ cấp trên của mình, hy vọng điều đó sẽ hữu ích.

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

Tôi không phản đối câu trả lời đã cho và được chấp nhận. Có một căn phòng cho những cạm bẫy hiệu suất có thể xảy ra. Bạn nên sử dụng giao diện Filterabe. Việc triển khai này sẽ hoạt động như ol'good ListView đã lọc không đồng bộ. Sau đó, tất cả những gì bạn cần là viết Filter của riêng bạn và khởi tạo nó theo phương thức getFilter() bị ghi đè;

Trong trường hợp của tôi, tôi đã sử dụng Filter để sắp xếp bộ điều hợp của nhiều mục (vâng, nhiều nhiều). Đó là junky phân loại nó trên UI-thread.

Vì vậy, tôi có lớp trừu tượng này

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 

} 

Và các lớp kế thừa:

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

} 
Các vấn đề liên quan