Recyclerview-单击搜索显示的结果将打开不正确的项目

时间:2018-08-04 05:00:25

标签: android android-recyclerview onclicklistener recycler-adapter android-room

我正在使用recyclerview来显示房间数据库中的笔记列表。我还添加了搜索功能。目前,我在MainActivity中有4个注释(此活动显示注释)。搜索时,如果得到的结果列表包含2个以上的注释,则单击它们时会显示正确的注释;但是,如果结果包含1个或2个注释,则始终显示列表中的前2个注释,而不是通过搜索过滤的注释。 这是我的代码:

模型类注意:

    @Entity(tableName = TABLE_NAME)
public class Note implements Serializable{

@Nullable
    private int Color;

    @PrimaryKey(autoGenerate = true)
    private long id;
    /** Not-null value. */

    private String Desc;
    private String Time;

    // KEEP FIELDS - put your custom fields here
    // KEEP FIELDS END

    public Note() {
    }


    public Note(String Desc, String Time) {
        this.Desc = Desc;
        this.Time = Time;
    }

    public int getColor() {
        return Color;
    }

    public void setColor(int color) {
        Color = color;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    /** Not-null value. */
    public String getDesc() {
        return Desc;
    }

    /** Not-null value; ensure this value is available before it is saved to the database. */
    public void setDesc(String Desc) {
        this.Desc = Desc;
    }

    public String getTime() {
        return Time;
    }

    public void setTime(String Time) {
        this.Time = Time;
    }

NotesAdapter:

public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.MyViewHolder> {

    public List<Note> list;
    private Context context;
    private List<Note> filteredList = new ArrayList<>();
    private ClickListener clickListener;
    public List<Note> selectednotes_list = new ArrayList<>();
    private String TAG = NotesAdapter.class.getSimpleName();


    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView mNoteDesc;
        public TextView mNoteTime;
        public RelativeLayout mcontainer;

        public MyViewHolder(View itemView) {
            super(itemView);
           itemView.setOnClickListener(this);
            mNoteTime = itemView.findViewById(R.id.note_time);
            mNoteDesc = itemView.findViewById(R.id.note_desc);
            mcontainer = itemView.findViewById(R.id.note_container);

        }

        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: ");
            clickListener.onClick(v,this.getLayoutPosition());
        }
/*

        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: ");
            clickListener.onClick(v,getLayoutPosition());
            //clickListener.onClick(filteredList.get(getAdapterPosition()));
        }
*/


    }

    public NotesAdapter(List<Note> list, Context context,List<Note> selectednotes_list) {
        this.list = list;
        this.filteredList = list;
        this.context = context;
        this.selectednotes_list = selectednotes_list;
        this.clickListener = (ClickListener) context;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.noteview,null,false);
        return new MyViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.mNoteTime.setText(list.get(position).getTime());
        holder.mcontainer.setBackgroundColor(Utils.getRandomMaterialColor(context, "50to300"));
        holder.mNoteDesc.setText(list.get(position).getDesc());
        // Change background color on select
        if (selectednotes_list.size() > 0) {
            if (selectednotes_list.contains(list.get(position)))
                holder.mcontainer.setBackgroundColor(ContextCompat.getColor(context, R.color.colorSecondary));
        }
    }

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


    public void filterList(List<Note> filter) {
        this.list = filter;
        notifyDataSetChanged();
    }


}

MainActivity:

public class MainActivity extends AppCompatActivity implements ClickListener{

    private StaggeredGridLayoutManager gridLayoutManager;
    private RecyclerView recyclerView;
    private List<Note> noteList, multiSelectList;
    public  NotesAdapter notesAdapter;
    private Notedatabase notedatabase;
    private String TAG = MainActivity.class.getSimpleName();
    private FloatingActionButton maddbtn;
    private int position;
    private SearchView mSearchView;
    private boolean isMultiSelect = false;
    private Menu context_menu;
    private ActionMode mActionMode;
    private CoordinatorLayout mCoordinatorLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        displayList();

/*

        notesList.addAll(noteList);

        List<Note> notesList = getNotes();
        notesAdapter = new NotesAdapter(notesList,MainActivity.this);
        recyclerView.setAdapter(notesAdapter);
        */
    }

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

      // Searchable config with searchview
        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        mSearchView.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
        mSearchView.setMaxWidth(Integer.MAX_VALUE);

        // Set Listener
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                // filter when query is submitted
                Log.d(TAG, "onQueryTextSubmit: " + query);
                notesAdapter.filterList(filter(query,noteList));
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // filter progressively as query changes
                Log.d(TAG, "onQueryTextChange: " + newText);
                notesAdapter.filterList(filter(newText,noteList));
                return false;
            }
        });

        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.action_search) {
            // search action
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        // close searchview
        if(!mSearchView.isIconified()) {
            mSearchView.setIconified(true);
            return;
        }

        super.onBackPressed();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == REQUEST_CODE) {
            if (resultCode == 1) {
                Log.d(TAG, "Request code is 1");
                noteList.add((Note) data.getSerializableExtra("note"));
                notesAdapter.notifyDataSetChanged();
            }
            else if(resultCode == 2) {
                Log.d(TAG, "Request code 2, update return");
                noteList.set(position, (Note) data.getSerializableExtra("note"));
                notesAdapter.notifyDataSetChanged();
            }
            else if(resultCode == 3) {
                Log.d(TAG, "Request code 3, delete return");
                Log.d(TAG, "Deleting this from list:" + (Note) data.getSerializableExtra("note"));
                noteList.remove(MainActivity.this.position);
                notesAdapter.notifyItemRemoved(MainActivity.this.position);
            }
        }
    }

    private void displayList() {
    notedatabase = Notedatabase.getInstance(MainActivity.this);
    new RetrieveTask(this).execute();
    }

    private void initViews() {
        recyclerView = findViewById(R.id.recyclerview);
        gridLayoutManager = new StaggeredGridLayoutManager(2,1);
        mCoordinatorLayout = findViewById(R.id.coordinatorLayout);

        recyclerView.setLayoutManager(gridLayoutManager);

        noteList = new ArrayList<>();
        multiSelectList = new ArrayList<>();

        notesAdapter = new NotesAdapter(noteList,MainActivity.this,multiSelectList);
        recyclerView.setAdapter(notesAdapter);

        maddbtn = findViewById(R.id.add_fab);
        maddbtn.setOnClickListener(v -> {
            Intent intent = new Intent(MainActivity.this,NoteActivity.class);
            startActivityForResult(intent,REQUEST_CODE);
        });
    }


    @Override
    public void onClick(View view, int pos) {
/*
        Log.d(TAG, "Recylerview item onClick: ");
        MainActivity.this.position  = pos;
        Intent intent = new Intent(MainActivity.this,NoteActivity.class);
        intent.putExtra("note",noteList.get(position));
        Log.d(TAG, "list.get(position): " + noteList.get(pos).getDesc());
        startActivityForResult(intent,REQUEST_CODE);
*/
    }

    @Override
    public void onClick(Note note) {
 /*
        Log.d(TAG, "onClick with args as note1");
        Intent intent = new Intent(MainActivity.this,NoteActivity.class);
        intent.putExtra("note",note);
        startActivityForResult(intent,REQUEST_CODE);*/
    }

    @Override
    public void onLongClick(View view, int pos) {
     /*   Log.d(TAG, "onLongClick ");
        if(!isMultiSelect) {
            multiSelectList = new ArrayList<Note>();
            isMultiSelect = true;

            if(mActionMode == null) {
                mActionMode = startActionMode(mActionModeCallback);
            }
        }

        multi_select(pos);*/
    }

    private void multi_select(int pos) {
        if(mActionMode != null) {
            if(multiSelectList.contains(noteList.get(pos))) {
                Log.d(TAG, "multi_select removed: " + multiSelectList.contains(noteList.get(pos)));
                multiSelectList.remove(noteList.get(pos));
            }
            else {
                Log.d(TAG, "multi_select added: " + multiSelectList.contains(noteList.get(pos)));
                multiSelectList.add(noteList.get(pos));
            }

            if(multiSelectList.size() > 0) mActionMode.setTitle("" + multiSelectList.size() + " selected");
            else mActionMode.setTitle("");
            refreshAdapter();
        }
    }

    private void refreshAdapter() {
    notesAdapter.selectednotes_list = multiSelectList;
    notesAdapter.list = noteList;
    notesAdapter.notifyDataSetChanged();
    }


    class RetrieveTask extends AsyncTask<Void,Void,List<Note>>{
        private WeakReference<MainActivity> weakReference;

        public RetrieveTask(MainActivity mainActivity) {
        weakReference = new WeakReference<>(mainActivity);
        }

        @Override
        protected List<Note> doInBackground(Void... voids) {
            if(weakReference.get()!=null)
                return weakReference.get().notedatabase.getNoteDao().getNotes();
            else
            return null;
        }

        @Override
        protected void onPostExecute(List<Note> notes) {
            if(notes!=null & notes.size()>0) {
                weakReference.get().noteList = notes;
                //weakReference.get().noteList.addAll(weakReference.get().getNotes());
                Log.d(TAG, "Result: " + notes);
                weakReference.get().notesAdapter = new NotesAdapter(notes,weakReference.get(),multiSelectList);
/*
                // Randomly set note background
                for(Note n:notes) {
                    n.setColor(getRandomMaterialColor(MainActivity.this,"500"));
                }
*/              weakReference.get().recyclerView.addOnItemTouchListener(new RecyclerTouchListener(recyclerView, getApplicationContext(), new ClickListener() {
                    @Override
                    public void onClick(View view, int pos) {
                        if (isMultiSelect)
                            multi_select(pos);
                        else {
                            Log.d(TAG, "Recylerview item onClick: ");
                            MainActivity.this.position = pos;
                            Intent intent = new Intent(MainActivity.this, NoteActivity.class);
                            intent.putExtra("note", noteList.get(position));
                            Log.d(TAG, "list.get(position): " + weakReference.get().noteList.get(position).getDesc());
                            startActivityForResult(intent, REQUEST_CODE);
                        }
                    }

                    @Override
                    public void onClick(Note note) {
                        Log.d(TAG, "onClick with args as note");
                        Intent intent = new Intent(MainActivity.this, NoteActivity.class);
                        intent.putExtra("note", note);
                        startActivityForResult(intent, REQUEST_CODE);
                    }

                    @Override
                    public void onLongClick(View view, int pos) {
                        Log.d(TAG, "onLongClick ");
                        if(!isMultiSelect) {
                            multiSelectList = new ArrayList<Note>();
                            isMultiSelect = true;

                            if(mActionMode == null) {
                                mActionMode = startActionMode(mActionModeCallback);
                            }
                        }

                        multi_select(pos);
                    }
                }));

                weakReference.get().recyclerView.setAdapter(weakReference.get().notesAdapter);
                weakReference.get().notesAdapter.notifyDataSetChanged();
            }
            else{
                displayErrorMsg();
            }
        }
    }

    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            //Prepare the menu
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.contextual_action,menu);
            context_menu = menu;
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            //mode.getCustomView().setBackgroundColor(getApplicationContext().getResources().getColor(android.R.color.white));
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_delete:
                        // display alert dialog
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

                        builder.setMessage("Delete " + multiSelectList.size() + " notes?");
                        builder.setCancelable(true);
                        builder.setPositiveButton(R.string.alert_yes,(dialog, which) -> {
                            // Deleting notes
                            for (int i = 0; i < multiSelectList.size(); i++) {
                                Log.d(TAG, "Deleting: " + multiSelectList.get(i));
                                notedatabase.getNoteDao().deleteNotes(multiSelectList.get(i));
                                noteList.remove(multiSelectList.get(i));
                            }
                            // Display Snackbar
                            displaySnackbar(mCoordinatorLayout,R.string.delete_success);
                            dialog.cancel();
                            // Refresh adapter
                            refreshAdapter();
                            // dismiss the contextual action bar
                            if(mActionMode!=null) mActionMode.finish();
                        });

                        builder.setNegativeButton(R.string.alert_no,(dialog, which) -> {
                            dialog.cancel();
                            if(mActionMode!=null) mActionMode.finish();
                        });

                        builder.setOnCancelListener(dialog1 -> {
                            Log.d(TAG, "onCancelListener: ");
                            if(mActionMode!=null) mActionMode.finish();
                        });

                    AlertDialog dialog = builder.create();
                        dialog.show();


               return true;

            default:
                return false;
            }
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
            isMultiSelect = false;
            multiSelectList = new ArrayList<Note>();
            refreshAdapter();
        }
    };

    @Override
    protected void onDestroy() {
        notedatabase.cleanUp();
        super.onDestroy();
    }

    private void displayErrorMsg() {
        Toast.makeText(MainActivity.this,R.string.failure_display,Toast.LENGTH_SHORT).show();
    }
}

任何帮助都广受赞赏!! 请!严重卡在这里

1 个答案:

答案 0 :(得分:0)

发现了! 我没有存储过滤器的结果,而是直接在filterList中调用它。

noteList = filter(newText, noteList);
notesAdapter.filterList(noteList);

以上几行为我做到了!