首页 > 解决方案 > Recyclerview 与 searchview 解除绑定问题

问题描述

我正在为我的 recyclerview 使用日期搜索过滤器,我的 performFiltering 日志给了我正确的记录集,recyclerview 显示的记录数是正确的,但数据不正确,我知道这是因为 recyclerview 回收视图但即使几个小时后,我找不到解绑数据的方法,以便显示准确的过滤结果。帮助!

    package com.emlocks.timeaccess;

import android.app.DatePickerDialog;
import android.app.Notification;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.DatePicker;
import android.widget.Filter;
import android.widget.Filterable;
import android.support.v7.widget.SearchView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.emlocks.timeaccess.R.layout.list_item1;

public class NotificationList extends AppCompatActivity {

    SharedPreferences prefs;


    private Gson gson;
    RecyclerView recyclerView;


    List<Map<String, String>> notifList;
    List<Map<String, String>> notifListFull;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
        prefs = getSharedPreferences(getResources().getString(R.string.prefs), MODE_PRIVATE);

        gson = new Gson();
        recyclerView = findViewById(R.id.notificationsRecycler);


        prefs = getSharedPreferences(getResources().getString(R.string.prefs), MODE_PRIVATE);

        notifList = gson.fromJson(prefs.getString("notifs", ""), new TypeToken<List<Map<String, String>>>() {
        }.getType());
        notifListFull = new ArrayList<>(notifList);

        recyclerView.setLayoutManager(new LinearLayoutManager(NotificationList.this));
        recyclerView.setAdapter(new NotificationListAdapter());


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.example_menu, menu);

        final MenuItem searchItem = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) searchItem.getActionView();

        searchView.setOnSearchClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar cal = Calendar.getInstance();
                int year = cal.get(Calendar.YEAR);
                int month = cal.get(Calendar.MONTH);
                int day = cal.get(Calendar.DAY_OF_MONTH);

                DatePickerDialog dilog = new DatePickerDialog(
                        NotificationList.this,
                        new DatePickerDialog.OnDateSetListener() {
                            @Override
                            public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                                String monthText ;
                                String dayText;
                                month = month + 1;
                                if(month < 10){
                                    monthText = "0" + month;
                                } else{
                                    monthText = String.valueOf(month);
                                }
                                if(dayOfMonth<10){
                                    dayText = "0" + dayOfMonth;
                                } else{
                                    dayText = String.valueOf(dayOfMonth);
                                }
                                String date = dayText + "/" + monthText + "/" + year;
                                searchView.setQuery(date, true);
                            }
                        }, year, month, day
                );
                dilog.show();

            }
        });

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                new NotificationListAdapter().getFilter().filter(newText);
                return false;
            }
        });
        return true;
    }


    class NotificationListAdapter extends RecyclerView.Adapter<NotificationList.NotificationListAdapter.VH> implements Filterable {

        @NonNull
        @Override
        public NotificationListAdapter.VH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
            View listItem1 = layoutInflater.inflate(list_item1, viewGroup, false);
            NotificationList.NotificationListAdapter.VH viewHolder = new NotificationList.NotificationListAdapter.VH(listItem1);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(@NonNull NotificationList.NotificationListAdapter.VH vh, int i) {
            Map<String, String> o = notifList.get(i);
            Log.d("TAG", "perform " + notifList.get(i).get("title"));
            vh.tv1.setText(o.get("title"));
            vh.tv2.setText(o.get("body"));

        }

        @Override
        public int getItemCount() {
            return notifList.size();
        }

        @Override
        public Filter getFilter() {
            return notifFilter;
        }

        private Filter notifFilter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                List<Map<String, String>> filteredList = new ArrayList<Map<String, String>>();
                if (constraint == null || constraint.length() == 0) {
                    filteredList.addAll(notifListFull);
                } else {
                    String filterPattern = constraint.toString().toLowerCase().trim();

                    for (Map<String, String> item : notifList) {
                        if (item.get("title").toLowerCase().contains(filterPattern)) {
                            filteredList.add(item);
                        }
                    }
                }

                FilterResults results = new FilterResults();

                results.values = filteredList;
                Log.d("TAG", "performFiltering: " + results.values);
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                notifList.clear();
                notifList.addAll((List<Map<String, String>>) results.values);
                notifyDataSetChanged();
            }
        };

        public class VH extends RecyclerView.ViewHolder {
            TextView tv1, tv2;

            public VH(View listItem1) {
                super(listItem1);
                this.tv1 = listItem1.findViewById(R.id.tvTitle);
                this.tv2 = listItem1.findViewById(R.id.tvbody);

            }
        }
    }
}

标签: androidandroid-recyclerview

解决方案


NotificationListAdapter每次都在制作新的,onQueryTextChange而不是使用 RecyclerView 的适配器。

@Override
public boolean onQueryTextChange(String newText) {
    recyclerView.getAdapter().getFilter().filter(newText);
    return false;
}

推荐阅读