过滤后,recyclerview中的项目错误

时间:2017-04-11 01:38:37

标签: android android-recyclerview

我有一个RecyclerView适配器如下: -

public class RecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder> {

        List<Data> list = Collections.emptyList();
        Context context;

        public RecyclerViewAdapter(List<Data> list, Context context) {
            this.list = list;
            this.context = context;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            //Inflate the layout, initialize the View Holder
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.apps_layout, parent, false);

            ViewHolder holder = new ViewHolder(v);
            return holder;

        }

    @Override
    public void onViewDetachedFromWindow(ViewHolder holder) {
        super.onViewDetachedFromWindow(holder);

        ((ViewHolder)holder).itemView.clearAnimation();
    }

    @Override
        public void onBindViewHolder(ViewHolder holder, int position) {

            //Use the provided View Holder on the onCreateViewHolder method to populate the current row on the RecyclerView
            holder.title.setText(list.get(position).title);
            holder.description.setText(list.get(position).description);

        }

    public void setFilter(List<Data> searched_data) {
        list = new ArrayList<>();
        list.addAll(searched_data);
        notifyDataSetChanged();
    }

        @Override
        public int getItemCount() {
            //returns the number of elements the RecyclerView will display
            return list.size();
        }

        @Override
        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
        }

        // Insert a new item to the RecyclerView on a predefined position
        public void insert(int position, Data data) {
            list.add(position, data);
            notifyItemInserted(position);
        }

        // Remove a RecyclerView item containing a specified Data object
        public void remove(Data data) {
            int position = list.indexOf(data);
            list.remove(position);
            notifyItemRemoved(position);
        }

    }

现在好了,因为你可以看到setFilter方法来过滤recyclelerview列表

这就是我怎么称呼它

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String s) {
               return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                List<Data> filteredModelList = filter(data, s);
                adapter.setFilter(filteredModelList);
                return true;
            }
        });

现在过滤器工作正常,当我点击它位置错误

我知道来自该位置的错误,因为点击时旧版的Recyclerview有旧位置索引我不知道如何修复它无论如何这里是onclicklistener

data = appsdata(); // load the list List<Data>

        Collections.sort(data); // sorting

        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);

        adapter = new RecyclerViewAdapter(data, this);
        recyclerView.setAdapter(adapter);
        recyclerView.setNestedScrollingEnabled(false);

        recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {

                String s = data.get(position).title;
                String ss = data.get(position).description;

                Intent intent = new Intent(MainAcitivity.this, Work.class);
                intent.putExtra("title", s);
                intent.putExtra("desc", ss);
                startActivity(intent);

            }

        }));

我知道这一行导致了问题

String s = data.get(position).title;

因为当列表未被过滤时它与旧版相同,我如何更新此recyclerview以便在启动Work.class时可以获得更新的索引

2 个答案:

答案 0 :(得分:1)

好的家伙,这对我来说部分起作用

我尝试通过添加

来更新数据列表
data = filteredModelList;  // add this line
过滤后

这很好用

@Override
            public boolean onQueryTextChange(String s) {
                List<Data> filteredModelList = filter(data, s);
                adapter.setFilter(filteredModelList);
                data = filteredModelList;  // add this line
                return true;
            }

现在我得到真正的索引但是当我搜索并清除列表时,列表是空的,因为我替换了数据列表:(

编辑: - 我通过黑客修复它并不是一个好方法但是有效

你可以看到旧的列表在编辑之前使用了上面的内容

我以前用来更改数据列表

 data = filteredModelList;  // add this line

然后新的数据列表只有过滤值,当你清除searchView时,那个数据列表是空的,因为它没有那些所有的应用程序列表我做的是我把新列表作为data_fix和onclicklistener我使用了datafix而不是数据清单

看看这个怎么样

RecyclerItemClickListener方法

String s = datafix.get(position).title;  // data.get to datafix.get
String ss = datafix.get(position).description; // data.get to datafix.get

现在开始过滤电话 我叫这个

datafix = filteredModelList; // instead of data = filteredModelList;

我也将它初始化为oncreate,因此在启动应用程序时它不是空的

data = appsdata(); // load the list List<Data>
datafix = appsdata(); // load the list List<Data>  added just below it to intialize

现在通过这种方式,即使您从searchView中清除并且索引可以正常,完整加载的应用列表//列表数据仍然保持完整且无法清除

答案 1 :(得分:0)

逻辑在于如何更新回收站视图项

<li id="tab-1"></li>
<p data-tab="tab-1">Content 1</p>
<script>
let id = document.getElementById("tab-1").id;
for (let el of document.querySelectorAll("*")) {
  for (let {name, value} of el.attributes) {  
  if (value === id && name !== "id") {
     document.querySelector(`[${name}="${id}"]`)
     .style.color = "green";
     break;
  }
  }
}
</script>
  

上述行不是必需的,public void setFilter(List<Data> searched_data) { list = new ArrayList<>(); list.addAll(searched_data); notifyDataSetChanged(); } 这一行非常重要。您看到将数据传递给适配器时,您正在创建适配器列表和外部列表之间的符号链接。因此,对外部列表进行任何更改,以更新适配器版本。只需调用adapter = new RecyclerViewAdapter(data, this);   只要对数据模型对象进行任何更改,请执行此操作。

更改以下内容

adapter.notifyDatasetChange method
  

要,

  List<Data> filteredModelList = filter(data, s);
                adapter.setFilter(filteredModelList);
                data = filteredModelList;  // add this line
                return true;