【问题标题】:Android: how do I maintain the View for CardViews in a RecyclerView list?Android:如何在 RecyclerView 列表中维护 CardViews 的视图?
【发布时间】:2017-01-31 23:31:21
【问题描述】:

我有一个 RecyclerView 列表,它显示了 CardViews 的垂直列表。 AppBar 有一个 action_search MenuItem,它在单击时处理 SearchView 方法。 SearchView 运行允许搜索 CardView 数据的过滤器方法。

我设置了一个 filterList 来保存从搜索结果中过滤的 CardView。 filter() 方法在执行搜索查询之前清除 filterList。问题是 filterList.clear() 破坏了现有 RecyclerView CardViews 的 View 并且 UI 恢复为空白 RecyclerView 布局。

如果我退出应用程序然后重新启动应用程序,RecyclerView 会正确加载 CardViews,当我单击搜索 MenuItem 时,我就可以正确搜索;也就是说,视图会动态且正确地更新,以仅显示与搜索文本查询匹配的 CardView。我在这里错过了什么?

MainActivity.java

public class MainActivity extends AppCompatActivity implements
    RecyclerItemClickListener {

    private MyRecylerAdapter adapter;
    ...
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.cardview_menu, menu);
        MenuItem item = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView item);            
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                adapter.filter(query);
                return true;
            }

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

 Adapter.java

 public class MyRecylerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

     private List<ListItem> listItems, filterList;
     private Context mContext;

     public MyRecylerAdapter(Context context, List<ListItem> listItems) {
         this.listItems = listItems;
         this.mContext = context;
         this.filterList = new ArrayList<>();
         // Copy the original list to the filter list to be used for setting row
         // values when returning search data items.
         this.filterList.addAll(this.listItems);
     }

     public void clear() {
         while (getItemCount() > 0) {
             remove(getItem(0));
         }
     }

     public void filter(final String text) {

     new Thread(new Runnable() {
         @Override
         public void run() {

            filterList.clear();

            if(TextUtils.isEmpty(text)) {
                filterList.addAll(listItems);
            } else {                    
                for (ListItem item : listItems) {
                    if (item.getTodo().toLowerCase().contains(text.toLowerCase())) {                        
                        filterList.add(item);
                    }
                }
            }

            // Set on UI Thread
            ((Activity) mContext).runOnUiThread(new Runnable() {
                @Override
                public void run() {                        
                    notifyDataSetChanged();
                }
            });
        }
    }).start();
} 

}

【问题讨论】:

    标签: android android-recyclerview android-adapter


    【解决方案1】:

    试试这个代码..在适配器中设置这个方法

    public void setFilter(ArrayList<ListItem> listItem) {
            listItems = new ArrayList<>();
            listItems.addAll(listItem);
            notifyDataSetChanged();
        }
    

    并在onQueryTextChange()中这样使用

    final ArrayList<ListItem> filteredModelList = filter(listItems, newText);
    adapter.setFilter(filteredModelList);
    

    这就是过滤方法。

    private ArrayList<ListItem> filter(ArrayList<ListItem> models, String query) {
            query = query.toLowerCase();
    
            final ArrayList<ListItem> filteredModelList = new ArrayList<>();
            for (ListItem model : models) {
                final String text = model.getTodo().toLowerCase();
                if (text.contains(query)) {
                    filteredModelList.add(model);
                }
            }
    
            return filteredModelList;
        }
    

    并从适配器构造函数中删除最后两行。使用此代码,您不必为过滤器创建第二个数组列表对象,因此您不需要清除您的数组列表对象。当您在 searchview 中编写或清除文本时效果很好。

    【讨论】:

    • 我会试一试的。
    • 好的..如果发生任何问题,请告诉我
    • 好的,做了一些小的修改,它运行良好!答案被接受并赞成。一个小问题:一旦输入一个字母(例如“z”)作为 SearchView 查询,如果用户退格删除“z”或用户单击 SearchView 中的“x”取消,我如何返回原始列表“z”搜索?
    • 我能够通过使用适配器清除并重新加载原始列表来修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    相关资源
    最近更新 更多