I am trying to create a recipe Keeper app that is able to store recipes into a room database and display them on the main home Fragment using a recycler view. every time I add something into the database it does not update the recycler view unless I close the app and open it again. When I do the new entry appears. How do i fix this?
This is my homeFragment code:
public class homeFragment extends Fragment {
ArrayList<recipeModel> homeRecipeModels = new ArrayList<recipeModel>();
Recipe_RecyclerViewAdapater adapter;
ImageButton add_button;
Dialog mDialog;
RecipeDatabase recipeDB;
recipeModel recipeViewModel;
Recipe_RecyclerViewAdapater recipeAdapter;
EditText recipe_edit, description_edit, prep_time_edit, cook_time_edit, total_time_edit;
Button next_button;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
add_button = view.findViewById(R.id.add_button);
// pop out one: making recipe
View popUpOne = inflater.inflate(R.layout.add_recipe_popup_1, null);
recipe_edit = popUpOne.findViewById(R.id.recipe_edit);
description_edit = popUpOne.findViewById(R.id.description_edit);
prep_time_edit = popUpOne.findViewById(R.id.prep_time_edit);
cook_time_edit = popUpOne.findViewById(R.id.cook_time_edit);
total_time_edit = popUpOne.findViewById(R.id.total_time_edit);
next_button = popUpOne.findViewById(R.id.save);
mDialog = new Dialog(requireContext());
//create recipe DB
RoomDatabase.Callback myCallBack = new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
}
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
}
};
recipeDB = Room.databaseBuilder(requireContext(), RecipeDatabase.class, "recipeDB").addCallback(myCallBack).build();
RecyclerView recyclerView = view.findViewById(R.id.homeRecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(true);
adapter = new Recipe_RecyclerViewAdapater(getContext());
recyclerView.setAdapter(adapter);
recipeViewModel = new ViewModelProvider(this).get(recipeModel.class);
recipeViewModel.getAllRecipes().observe(getViewLifecycleOwner(), recipes -> {
Log.d("update recyclerView", "view Updated");
adapter.setRecipe(recipes);
});
// on click listener to add a recipe
add_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO: using setCOntentView(popUpOne) makes the pop up smaller than using R.id.add_recipe_popup_1
mDialog.setContentView(popUpOne);
mDialog.show();
}
});
next_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("next clicked", "saved data");
String insertRecipeName = recipe_edit.getText().toString();
String insertDescription = description_edit.getText().toString();
String insertPrepTimeStr = prep_time_edit.getText().toString();
int insertPrepTime = Integer.parseInt(insertPrepTimeStr);
String insertCookTimeStr = cook_time_edit.getText().toString();
int insertCookTime = Integer.parseInt(insertCookTimeStr);
String insertTotalTimeStr = total_time_edit.getText().toString();
int insertTotalTime = Integer.parseInt(insertTotalTimeStr);
Recipe recipe1 = new Recipe(0,insertRecipeName,insertPrepTime, insertCookTime, insertTotalTime, insertDescription);
addNewRecipe(recipe1);
mDialog.dismiss();
}
});
return view;
}
public void addNewRecipe(Recipe recipe){
ExecutorService executorService = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());
executorService.execute(new Runnable() {
@Override
public void run() {
//background task
recipeDB.getRecipeDAO().addRecipe(recipe);
//on finish task
requireActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(requireContext(), "added to DB", Toast.LENGTH_SHORT).show();
}
});
}
});
}
RecyclerView_adapter code:
package com.mobileapp.cookie_jar;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class Recipe_RecyclerViewAdapater extends RecyclerView.Adapter<Recipe_RecyclerViewAdapater.MyViewHolder> {
Context context;
List<Recipe> recipes;
public Recipe_RecyclerViewAdapater(Context context){
this.context = context;
this.recipes = new ArrayList<>();
}
@NonNull
@Override
public Recipe_RecyclerViewAdapater.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.overview_recycler_view_row, parent, false);
return new Recipe_RecyclerViewAdapater.MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull Recipe_RecyclerViewAdapater.MyViewHolder holder, int position) {
if (recipes != null) {
Recipe current = recipes.get(position);
holder.recipe.setText(current.getRecipeName());
holder.time.setText(String.valueOf(current.getCookTime()));
holder.description.setText(current.getDescription());
//holder.imageView.setImageResource(recipeModels.get(position).getRecipeImage());
}
// } else {
// //holder.recipe.setText("No Recipes");
// }
}
void setRecipe(List<Recipe> data){
recipes = data;
notifyDataSetChanged();
Log.d("Changes notified", "changeds Comitted");
}
@Override
public int getItemCount() {
if (recipes != null){
return recipes.size();
} else {
return 0;
}
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView recipe, time, description;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.food_image);
recipe = itemView.findViewById(R.id.recipe_name);
time = itemView.findViewById(R.id.recipe_cook_time);
description = itemView.findViewById(R.id.recipe_description);
}
}
}
RecipeModel code:
public class recipeModel extends AndroidViewModel{
RecipeDAO recipeDAO;
RecipeDatabase recipeDB;
LiveData<List<Recipe>> allRecipes;
public recipeModel(Application application) {
super(application);
recipeDB = RecipeDatabase.getInstance(application);
recipeDAO = recipeDB.getRecipeDAO();
allRecipes = recipeDAO.getAllRecipes();
}
LiveData<List<Recipe>> getAllRecipes() {
return allRecipes;
}
RecipeDAO
@Dao
public interface RecipeDAO {
@Insert
public void addRecipe(Recipe recipe);
@Update
public void updateRecipe(Recipe recipe);
@Delete
public void deleteRecipe(Recipe recipe);
@Query("select * from recipe")
LiveData<List<Recipe>> getAllRecipes();
@Query("select * from recipe where recipe_id==:Recipe_id")
public Recipe getRecipe(int Recipe_id);
}
@Dao
interface IngredientDAO {
@Insert
public void addIngredient(Ingredient ingredient);
@Update
public void updateIngredient(Ingredient ingredient);
@Delete
public void deleteIngredient(Ingredient ingredient);
@Query("select * from ingredient")
public List<Ingredient> getAllIngredients();
@Query("select * from ingredient where ingredient_name==:Ingredient_name")
public Ingredient getIngredient(String Ingredient_name);
}
@Dao
interface StepsDAO {
@Insert
public void addSteps(Steps steps);
@Update
public void updateSteps(Steps steps);
@Delete
public void deleteSteps(Steps step);
@Query("select * from steps")
public List<Steps> getAllSteps();
@Query("select * from steps where recipe_id==:Recipe_id")
public Steps getSteps(int Recipe_id);
}