如何在 RecyclerView 中使 Material CardView 可检查
How to make Material CardView, Checkable, in RecyclerView
我制作了一个 android 笔记应用程序,我想制作笔记 Material CardView,Checkable。
我想要这种行为。当我长按每个笔记时,每个笔记都会 checked/selected(根据 material 设计卡片视图 setChecked 行为进行检查)。
它是一个带有 RecyclerView 和实现注释的 Room 持久性数据库。每个笔记布局都是一个 Material CardView。我有一个名为“NotesAdapter”的适配器、一个模型实体“Note”和名为“MyNotesActivity”的主要Activity。当然我还有一些文件,但我没有包含它们,因为我没有把整个项目都放在一起供你阅读。如果你想要他们,我会为你提出问题。
我已经试过了,但不能正常工作。
在 NotesAdapter 中,行“noteHolder.noteCardView.toggle();”
noteHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
//When long clicking(holding click) on note(note title, note body text, note date).
listener.onNoteLongClick(note);
noteHolder.noteCardView.toggle();
return true;
}
});
当我长按时它确实被选中了,但是当我向下滚动时,其他一些笔记也会被选中。
例如
https://gfycat.com/incomparablepowerfullarva
我的“NotesAdapter.java”代码:
//implements Filterable is for some other feature, that has nothing to do with this question.
public class NotesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
public ArrayList<Note> notes;
public ArrayList<Note> notesFull;
private Context context;
private NoteEventListener listener;
private DeleteThisNoteListener deleteThisNoteListener;
public NotesAdapter(ArrayList<Note> notes, Context context, DeleteThisNoteListener deleteThisNoteListener) {
this.notes = notes;
this.context = context;
this.deleteThisNoteListener = deleteThisNoteListener;
notesFull = new ArrayList<>(notes);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.note_layout, parent, false);
return new NoteHolder(v);
}
//Displays data at specified position.
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
final NoteHolder noteHolder = (NoteHolder) holder;
final Note note = getNote(position);
if (note != null) {
//Entering text to each Text fields.
noteHolder.noteTitle.setText(note.getNoteTitle());
noteHolder.noteBodyText.setText(note.getNoteBodyText());
noteHolder.noteDate.setText(NoteUtils.dateFromLong(note.getNoteDate()));
noteHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
//When long clicking(holding click) on note(note title, note body text, note date).
listener.onNoteLongClick(note);
noteHolder.noteCardView.toggle();
return true;
}
});
noteHolder.moreMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deleteThisNoteListener.onDeleteThisNoteClick(note, view, noteHolder.getBindingAdapterPosition());
}
});
}
}
//Gets the particular note and its position.
public Note getNote(int position) {
return notes.get(position);
}
//Gets how many notes are there.
@Override
public int getItemCount() {
return notes.size();
}
//setListener sets all listeners
public void setListener(NoteEventListener listener, DeleteThisNoteListener deleteThisNoteListener) {
this.listener = listener;
this.deleteThisNoteListener = deleteThisNoteListener;
}
static class NoteHolder extends RecyclerView.ViewHolder {
TextView noteTitle, noteBodyText, noteDate;
MaterialButton moreMenu;
MaterialCardView noteCardView;
public NoteHolder(@NonNull View itemView) {
super(itemView);
noteCardView = itemView.findViewById(R.id.note);
noteTitle = itemView.findViewById(R.id.note_title);
noteBodyText = itemView.findViewById(R.id.note_body_text);
noteDate = itemView.findViewById(R.id.note_date);
moreMenu = itemView.findViewById(R.id.more_menu_button);
}
}
}
我的“MyNotesActivity.java”
public class MyNotesActivity extends AppCompatActivity implements NoteEventListener, DeleteThisNoteListener {
private MaterialToolbar searchTopBar;
private MaterialToolbar pageTitleTopBar;
private MaterialToolbar selectNotesTopBar;
private NotesDAO dao;
private NotesAdapter adapter;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
public static final String TAG = "MyNotie";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_notes);
BottomAppBar bottomAppBar = findViewById(R.id.bottom_app_bar);
setSupportActionBar(bottomAppBar);
layoutManager = new LinearLayoutManager(this);
recyclerView = findViewById(R.id.notes_list);
recyclerView.setLayoutManager(layoutManager);
dao = NotesDB.getInstance(this).notesDAO();
FloatingActionButton add_new_note_button = findViewById(R.id.add_new_note);
add_new_note_button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
addNotes("This is a test note.", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin et ante quis nibh blandit vehicula non sit amet dui.");
addNotes("New note!", "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");
addNotes("Check this new note!", "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.");
addNotes("Cool note!", "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
addNotes("Wrote it all down!", "Nullam imperdiet placerat porttitor. Ut ac urna sed magna gravida eleifend. ");
loadNotes();
}
});
recyclerView.addOnScrollListener(onScrollListener);
}
private void addNotes(String noteTitle, String noteBodyText) {
for (int i=0; i<2; i++) {
Note testNote = new Note();
long date = new Date().getTime();
testNote.setNoteTitle(noteTitle);
testNote.setNoteBodyText(noteBodyText);
testNote.setNoteDate(date);
dao.insertNote(testNote);
adapter.notesFull.add(testNote);
adapter.notes.add(testNote);
}
}
//When resuming the app while on sleep or opening the app this onResume
method is called.
@Override
protected void onResume() {
super.onResume();
loadNotes(); //loads/reloads notes from database.
}
}
我的模型“Note.java”:
@Entity(tableName = "notes")
public class Note {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "isNewNote")
private Boolean isNewNote = true;
@ColumnInfo(name = "noteTitle")
private String noteTitle;
@ColumnInfo(name = "text")
private String noteBodyText;
@ColumnInfo(name = "date")
private long noteDate;
public Note() {
}
public String getNoteTitle() {
return noteTitle;
}
public void setNoteTitle(String noteTitle) {
this.noteTitle = noteTitle;
}
public String getNoteBodyText() {
return noteBodyText;
}
public void setNoteBodyText(String noteBodyText) {
this.noteBodyText = noteBodyText;
}
public long getNoteDate() {
return noteDate;
}
public void setNoteDate(long noteDate) {
this.noteDate = noteDate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@NonNull
public Boolean getIsNewNote() {
return isNewNote;
}
public void setIsNewNote(@NonNull Boolean newNote) {
isNewNote = newNote;
}
@NonNull
@Override
public String toString() {
return "Note{" +
"id=" + id +
", noteDate=" + noteDate +
'}';
}
}
请给我一些建议,因为我找不到任何有效的解决方案...在此先感谢您!
其实我明白了!我从这个人那里得到了这个想法:
当他展示他的 RecyclerViewAdapter 和 Model 并在 RecyclerViewAdapter 中看到这个时:
holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
model.setSelected(!model.isSelected());
holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
}
});
我做了这个:
“NotesAdapter.java”
noteHolder.noteCardView.setChecked(note.isChecked());
noteHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
//When long clicking(holding click) on note(note title, note body text,
note date).
note.setChecked(!note.isChecked());
noteHolder.noteCardView.setChecked(note.isChecked());
return true;
}
});
并在模型“Note.java”
中添加了 getter、“isChecked”和 setter“setChecked”
public class Note {
//The rest that are not mentioned, remain unchanged.
@Ignore
private boolean isChecked;
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
}
这就解决了!
我希望这会帮助别人!它可能不是很好,但我希望它会有所帮助!感谢您看到这个 post!
我制作了一个 android 笔记应用程序,我想制作笔记 Material CardView,Checkable。 我想要这种行为。当我长按每个笔记时,每个笔记都会 checked/selected(根据 material 设计卡片视图 setChecked 行为进行检查)。
它是一个带有 RecyclerView 和实现注释的 Room 持久性数据库。每个笔记布局都是一个 Material CardView。我有一个名为“NotesAdapter”的适配器、一个模型实体“Note”和名为“MyNotesActivity”的主要Activity。当然我还有一些文件,但我没有包含它们,因为我没有把整个项目都放在一起供你阅读。如果你想要他们,我会为你提出问题。
我已经试过了,但不能正常工作。 在 NotesAdapter 中,行“noteHolder.noteCardView.toggle();”
noteHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
//When long clicking(holding click) on note(note title, note body text, note date).
listener.onNoteLongClick(note);
noteHolder.noteCardView.toggle();
return true;
}
});
当我长按时它确实被选中了,但是当我向下滚动时,其他一些笔记也会被选中。
例如
https://gfycat.com/incomparablepowerfullarva
我的“NotesAdapter.java”代码:
//implements Filterable is for some other feature, that has nothing to do with this question.
public class NotesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
public ArrayList<Note> notes;
public ArrayList<Note> notesFull;
private Context context;
private NoteEventListener listener;
private DeleteThisNoteListener deleteThisNoteListener;
public NotesAdapter(ArrayList<Note> notes, Context context, DeleteThisNoteListener deleteThisNoteListener) {
this.notes = notes;
this.context = context;
this.deleteThisNoteListener = deleteThisNoteListener;
notesFull = new ArrayList<>(notes);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.note_layout, parent, false);
return new NoteHolder(v);
}
//Displays data at specified position.
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
final NoteHolder noteHolder = (NoteHolder) holder;
final Note note = getNote(position);
if (note != null) {
//Entering text to each Text fields.
noteHolder.noteTitle.setText(note.getNoteTitle());
noteHolder.noteBodyText.setText(note.getNoteBodyText());
noteHolder.noteDate.setText(NoteUtils.dateFromLong(note.getNoteDate()));
noteHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
//When long clicking(holding click) on note(note title, note body text, note date).
listener.onNoteLongClick(note);
noteHolder.noteCardView.toggle();
return true;
}
});
noteHolder.moreMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deleteThisNoteListener.onDeleteThisNoteClick(note, view, noteHolder.getBindingAdapterPosition());
}
});
}
}
//Gets the particular note and its position.
public Note getNote(int position) {
return notes.get(position);
}
//Gets how many notes are there.
@Override
public int getItemCount() {
return notes.size();
}
//setListener sets all listeners
public void setListener(NoteEventListener listener, DeleteThisNoteListener deleteThisNoteListener) {
this.listener = listener;
this.deleteThisNoteListener = deleteThisNoteListener;
}
static class NoteHolder extends RecyclerView.ViewHolder {
TextView noteTitle, noteBodyText, noteDate;
MaterialButton moreMenu;
MaterialCardView noteCardView;
public NoteHolder(@NonNull View itemView) {
super(itemView);
noteCardView = itemView.findViewById(R.id.note);
noteTitle = itemView.findViewById(R.id.note_title);
noteBodyText = itemView.findViewById(R.id.note_body_text);
noteDate = itemView.findViewById(R.id.note_date);
moreMenu = itemView.findViewById(R.id.more_menu_button);
}
}
}
我的“MyNotesActivity.java”
public class MyNotesActivity extends AppCompatActivity implements NoteEventListener, DeleteThisNoteListener {
private MaterialToolbar searchTopBar;
private MaterialToolbar pageTitleTopBar;
private MaterialToolbar selectNotesTopBar;
private NotesDAO dao;
private NotesAdapter adapter;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
public static final String TAG = "MyNotie";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_notes);
BottomAppBar bottomAppBar = findViewById(R.id.bottom_app_bar);
setSupportActionBar(bottomAppBar);
layoutManager = new LinearLayoutManager(this);
recyclerView = findViewById(R.id.notes_list);
recyclerView.setLayoutManager(layoutManager);
dao = NotesDB.getInstance(this).notesDAO();
FloatingActionButton add_new_note_button = findViewById(R.id.add_new_note);
add_new_note_button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
addNotes("This is a test note.", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin et ante quis nibh blandit vehicula non sit amet dui.");
addNotes("New note!", "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");
addNotes("Check this new note!", "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.");
addNotes("Cool note!", "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
addNotes("Wrote it all down!", "Nullam imperdiet placerat porttitor. Ut ac urna sed magna gravida eleifend. ");
loadNotes();
}
});
recyclerView.addOnScrollListener(onScrollListener);
}
private void addNotes(String noteTitle, String noteBodyText) {
for (int i=0; i<2; i++) {
Note testNote = new Note();
long date = new Date().getTime();
testNote.setNoteTitle(noteTitle);
testNote.setNoteBodyText(noteBodyText);
testNote.setNoteDate(date);
dao.insertNote(testNote);
adapter.notesFull.add(testNote);
adapter.notes.add(testNote);
}
}
//When resuming the app while on sleep or opening the app this onResume
method is called.
@Override
protected void onResume() {
super.onResume();
loadNotes(); //loads/reloads notes from database.
}
}
我的模型“Note.java”:
@Entity(tableName = "notes")
public class Note {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "isNewNote")
private Boolean isNewNote = true;
@ColumnInfo(name = "noteTitle")
private String noteTitle;
@ColumnInfo(name = "text")
private String noteBodyText;
@ColumnInfo(name = "date")
private long noteDate;
public Note() {
}
public String getNoteTitle() {
return noteTitle;
}
public void setNoteTitle(String noteTitle) {
this.noteTitle = noteTitle;
}
public String getNoteBodyText() {
return noteBodyText;
}
public void setNoteBodyText(String noteBodyText) {
this.noteBodyText = noteBodyText;
}
public long getNoteDate() {
return noteDate;
}
public void setNoteDate(long noteDate) {
this.noteDate = noteDate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@NonNull
public Boolean getIsNewNote() {
return isNewNote;
}
public void setIsNewNote(@NonNull Boolean newNote) {
isNewNote = newNote;
}
@NonNull
@Override
public String toString() {
return "Note{" +
"id=" + id +
", noteDate=" + noteDate +
'}';
}
}
请给我一些建议,因为我找不到任何有效的解决方案...在此先感谢您!
其实我明白了!我从这个人那里得到了这个想法:
holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
model.setSelected(!model.isSelected());
holder.view.setBackgroundColor(model.isSelected() ? Color.CYAN : Color.WHITE);
}
});
我做了这个: “NotesAdapter.java”
noteHolder.noteCardView.setChecked(note.isChecked());
noteHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
//When long clicking(holding click) on note(note title, note body text,
note date).
note.setChecked(!note.isChecked());
noteHolder.noteCardView.setChecked(note.isChecked());
return true;
}
});
并在模型“Note.java”
中添加了 getter、“isChecked”和 setter“setChecked”public class Note {
//The rest that are not mentioned, remain unchanged.
@Ignore
private boolean isChecked;
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
}
这就解决了! 我希望这会帮助别人!它可能不是很好,但我希望它会有所帮助!感谢您看到这个 post!