Я работаю над приложением Android Note. И я хочу удалить несколько выбранных элементов одновременно из RecyclerView, а также из базы данных SQLite. Для этого я использую контекстную панель действий. Но когда я удаляю некоторые элементы, появляется следующая ошибка:
java.lang.NullPointerException: попытка вызвать метод интерфейса void com.notes.Adapter $ OnClickAction.onClickAction () для пустой ссылки на объект по адресу com.notes.Adapter $ 1.onLongClick
Как решить эту проблему?
Adapter.java
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private LayoutInflater inflater;
public List<Note> notes, selected;
OnClickAction receiver;
public int id;
public interface OnClickAction {
void onClickAction();
}
Adapter(Context context, List<Note> notes){
this.inflater = LayoutInflater.from(context);
this.notes = notes;
this.selected=new ArrayList<>();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = inflater.inflate(R.layout.note_item,viewGroup,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, final int i) {
final Note item = notes.get(i);
String title = notes.get(i).getTitle();
String date = notes.get(i).getDate();
String time = notes.get(i).getTime();
final long id = notes.get(i).getId();
Log.d("NC" ,"Date on: "+date);
viewHolder.nTitle.setText(title);
viewHolder.nDate.setText(date);
viewHolder.nTime.setText(time);
viewHolder.nID.setText(String.valueOf(notes.get(i).getId()));
viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (selected.contains(item)) {
selected.remove(item);
unhighlightView(viewHolder);
} else {
selected.add(item);
highlightView(viewHolder);
}
receiver.onClickAction();
return true;
}
});
if (selected.contains(item))
highlightView(viewHolder);
else
unhighlightView(viewHolder);
}
private void highlightView(ViewHolder holder) {
holder.itemView.setBackgroundColor(Color.CYAN);
}
private void unhighlightView(ViewHolder holder) {
holder.itemView.setBackgroundColor(Color.WHITE);
}
@Override
public int getItemCount() {
return notes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView nTitle,nDate,nTime,nID;
public ViewHolder(@NonNull final View itemView) {
super(itemView);
nTitle = itemView.findViewById(R.id.nTitle);
nDate = itemView.findViewById(R.id.nDate);
nTime = itemView.findViewById(R.id.nTime);
nID = itemView.findViewById(R.id.listId);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// notifyDataSetChanged();
Intent i = new Intent(v.getContext(),NoteDetails.class);
i.putExtra("ID",notes.get(getAdapterPosition()).getId());
v.getContext().startActivity(i);
itemView.setBackgroundColor(Color.GRAY);
}
});
}
}
public List<Note> getSelected() {
return selected;
}
public void setActionModeReceiver(OnClickAction receiver) {
this.receiver = receiver;
}
public void clearSelected() {
selected.clear();
notifyDataSetChanged();
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements Adapter.OnClickAction {
RecyclerView recyclerView;
Adapter adapter;
NoteDatabase noteDatabase;
long id;
ActionMode actionMode;
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.delete_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.dlt:
delete();
mode.finish();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
adapter.clearSelected();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
noteDatabase = new NoteDatabase(this);
recyclerView = findViewById(R.id.listofnotes);
FloatingActionButton button = findViewById(R.id.buttonadd);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Add New Note", Toast.LENGTH_SHORT).show();
Intent i = new Intent(view.getContext(), AddNote.class);
startActivity(i);
}
});
}
public void delete() {
List<Note> newnote=adapter.getSelected();
Log.d("NC","selected "+adapter.selected);
for (int i=0; i<newnote.size(); i++){
long id=newnote.get(i).getId();
noteDatabase.deleteNote(id);
Log.d("NC", "deleted: "+id);
List<Note> getAllNotes = noteDatabase.getAllNotes();
adapter=new Adapter(this,getAllNotes);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
Toast.makeText(getApplicationContext(),"Note Deleted",Toast.LENGTH_SHORT).show();
}
private void displayList(List<Note> allNotes) {
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new Adapter(this, allNotes);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.dltall) {
noteDatabase.deleteAll();
List<Note> notes = noteDatabase.getAllNotes();
Log.d("NC", "Note after dlt " + notes);
displayList(notes);
Toast.makeText(this, "All Notes Deleted", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
List<Note> getAllNotes = noteDatabase.getAllNotes();
if (getAllNotes.isEmpty()) {
} else {
displayList(getAllNotes);
adapter.setActionModeReceiver((Adapter.OnClickAction)this);
}
}
public void onClickAction() {
int selected = adapter.getSelected().size();
if (actionMode == null) {
actionMode = startActionMode(actionModeCallback);
actionMode.setTitle("Selected: " + selected);
} else {
if (selected == 0) {
actionMode.finish();
} else {
actionMode.setTitle("Selected: " + selected);
adapter.notifyDataSetChanged();
}
}
}
}