I am trying to remove Items from my recycler view. Every time I click on an item in my recycler view it provides me with this error.
java.lang.NullPointerException: Attempt to invoke virtual method 'void uk.edu.le.co2103.myrecipebook.RecipeListAdapter.removeItem(int, java.util.List)' on a null object reference
I have made sure that my list has been initalized and used a log to ensure that both position and the list have values in them.
List: [uk.edu.le.co2103.myrecipebook.Recipe@f4d5298, uk.edu.le.co2103.myrecipebook.Recipe@ca6aaf1] D/MAIN ACTIVITY: Index: 0
Here is my Main Activity code
public class MainActivity extends AppCompatActivity implements
RecipeListAdapter.OnItemClickListener {
private static final String TAG = "MAIN ACTIVITY";
private static final int RESULT_UPDATED = 300;
private RecipeViewModel mRecipeViewModel;
public static final int NEW_WORD_ACTIVITY_REQUEST_CODE = 1;
public String Name;
public String Ingredients;
public String Method;
private RecipeListAdapter mAdapter;
private RecipeDao recDao;
Menu menu;
List<Recipe> recipesList = new ArrayList<>();
ListView search_items;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
RecipeListAdapter mAdapter = new RecipeListAdapter(this);
recyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(MainActivity.this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecipeViewModel = new ViewModelProvider(this).get(RecipeViewModel.class);
Log.d(TAG, "SIZE OF LIST: "+ recipesList);
mRecipeViewModel.getAllRecipes().observe(this, new Observer<List<Recipe>>() {
@Override
public void onChanged(@Nullable final List<Recipe> recipes) {
// Update the cached copy of the words in the adapter.
int size = mAdapter.getItemCount();
Log.d(TAG, "List of List : " + recipes);
recipesList= recipes;
mAdapter.setWords(recipes);
}
});
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddRecipeActivity.class);
startActivityForResult(intent, NEW_WORD_ACTIVITY_REQUEST_CODE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NEW_WORD_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
ArrayList<String> rData = data.getStringArrayListExtra(AddRecipeActivity.EXTRA_REPLY);
String name = rData.get(0);
String ingredients = rData.get(1);
String method = rData.get(2);
Recipe recipe = new Recipe(name, ingredients, method);
RecipeViewModel.insert(recipe);
}
else {
Toast.makeText(
getApplicationContext(),
R.string.empty_not_saved,
Toast.LENGTH_LONG).show();
}
}
@Override
public void onItemClick(int position, View view) {
Log.d(TAG, "onItemClick Position: " + position);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("Edit or Delete...");
alertDialog.setPositiveButton("Edit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
recipesList.get(position); //clicked item
Intent update = new Intent(MainActivity.this, UpdateRecipeActivity.class);
update.putExtra("Name", recipesList.get(position).getName()); //
update.putExtra("Ingredients", recipesList.get(position).getIngredients());
update.putExtra("Method", recipesList.get(position).getMethod());
startActivity(update);
}
});
alertDialog.setNegativeButton("Delete", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Delete
Log.d(TAG, "List: " + recipesList);
Log.d(TAG, "Index: " + position);
int removeIndex = position;
recipesList.remove(removeIndex);
}
});
alertDialog.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alertDialog.show();
}
Here is my adapter code
public class RecipeListAdapter extends
RecyclerView.Adapter<RecipeListAdapter.RecipeViewHolder> {
private static final String TAG = "ADAPTER";
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position, View view);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView recipeItemView;
private RecipeViewHolder(View itemView) {
super(itemView);
recipeItemView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (mListener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
mListener.onItemClick(position, v);
}
}
}
});
}
@Override
public void onClick(View view) {
mListener.onItemClick(getAdapterPosition(), view);
}
}
private final LayoutInflater mInflater;
private List<Recipe> mRecipes; // Cached copy of words
RecipeListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
@Override
public RecipeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.recyclerview_item, parent, false);
return new RecipeViewHolder(itemView);
}
@Override
public void onBindViewHolder(RecipeViewHolder holder, int position) {
if (mRecipes != null) {
Recipe current = mRecipes.get(position);
holder.recipeItemView.setText(current.getName());
} else {
// Covers the case of data not being ready yet.
holder.recipeItemView.setText("No Recipes");
}
}
void setWords(List<Recipe> recipes){
mRecipes = recipes;
notifyDataSetChanged();
}
public void deleteItem(final int position) {
mRecipes.remove(position);
notifyItemRemoved(position);
}
@Override
public int getItemCount() {
if (mRecipes != null)
return mRecipes.size();
else return 0;
}
public interface OnNoteListener{}
}
Here is the full error output
2020-04-02 15:27:30.553 5522-5522/uk.edu.le.co2103.myrecipebook E/AndroidRuntime: FATAL EXCEPTION: main
Process: uk.edu.le.co2103.myrecipebook, PID: 5522
java.lang.NullPointerException: Attempt to invoke virtual method 'void uk.edu.le.co2103.myrecipebook.RecipeListAdapter.deleteItem(int)' on a null object reference
at uk.edu.le.co2103.myrecipebook.MainActivity$4.onClick(MainActivity.java:133)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7464)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:955)
I changed your adapter. I found some problems :
public class RecipeListAdapter extends
RecyclerView.Adapter<RecipeListAdapter.RecipeViewHolder> {
private static final String TAG = "ADAPTER";
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position, View view);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView recipeItemView;
private RecipeViewHolder(View itemView) {
super(itemView);
recipeItemView = itemView.findViewById(R.id.textView);
itemView.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
if (mListener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
mListener.onItemClick(position, v);
}
}
}
});
}
@Override
public void onClick(View view) {
mListener.onItemClick(getAdapterPosition(), view);
}
}
private final LayoutInflater mInflater;
private List<Recipe> mRecipes; // Cached copy of words
RecipeListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
@Override
public RecipeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.recyclerview_item, parent, false);
return new RecipeViewHolder(itemView);
}
@Override
public void onBindViewHolder(RecipeViewHolder holder, int position) {
if (mRecipes != null) {
Recipe current = mRecipes.get(position);
holder.recipeItemView.setText(current.getName());
} else {
// Covers the case of data not being ready yet.
holder.recipeItemView.setText("No Recipes");
}
}
void setWords(List<Recipe> recipes){
mRecipes = recipes;
notifyDataSetChanged();
}
public void deleteItem(final int position) {
mRecipes.remove(position);
notifyItemRemoved(position);
}
@Override
public int getItemCount() {
if (mRecipes != null)
return mRecipes.size();
else return 0;
}
public interface OnNoteListener{}
}