`my issue is that when I create or update recipes, those created and updated recipes would not display in the cookbook fragment unless I navigate to a different navigation tab like favourite or map using the bottom navigation bar, then navigate back to the Cookbook fragment.
to summarise: my issue is to do with refreshing or updating the data in the Cookbook fragment when a user adds or updates a recipe.
the classes I am using to handle the crud operations and display the list of recipes are CookbookFragment, CookbookAdapter, AddActivity, UpdateActivity, MyRecipe and RecipeDatabase:
CookbookFragment:
public class CookbookFragment extends Fragment implements CookbookAdapter.RecipeItemClickListener {
private FragmentCookbookBinding binding;
private RecyclerView recyclerView;
private FloatingActionButton add_button;
private CookbookAdapter adapter;
private List<MyRecipe> recipes;
private RecipeDatabase recipeDatabase;
// this works public View onCreateView(@NonNull LayoutInflater inflater,
// ViewGroup container, Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentCookbookBinding.inflate(inflater, container, false);
View root = binding.getRoot();
recyclerView = root.findViewById(R.id.recyclerview);
add_button = root.findViewById(R.id.add_button);
// Set up RecyclerView and its adapter
recipes = new ArrayList<>();
adapter = new CookbookAdapter(recipes, this);
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
recyclerView.setAdapter(adapter);
// Set up FAB click listener for adding a new recipe
add_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(requireContext(), AddActivity.class);
startActivity(intent);
}
});
recipeDatabase = new RecipeDatabase(requireContext());
storeDataInArrays();
return root;
}
void storeDataInArrays() {
Log.d("CookbookFragment", "storeDataInArrays start");
Cursor cursor = recipeDatabase.readAllData();
try {
if (cursor.getCount() == 0) {
Toast.makeText(requireContext(), "No data", Toast.LENGTH_SHORT).show();
} else {
while (cursor.moveToNext()) {
String recipeTitle = cursor.getString(1);
String recipeIngredients = cursor.getString(2);
String recipeInstructions = cursor.getString(3);
int recipeTimeToCook = cursor.getInt(4);
// Create a MyRecipe object and add it to the recipes list
MyRecipe recipe = new MyRecipe(recipeTitle, recipeIngredients, recipeInstructions, recipeTimeToCook);
recipe.setId(cursor.getLong(0));
recipes.add(recipe);
}
Log.d("CookbookFragment", "Number of recipes: " + recipes.size());
Log.d("CookbookFragment", "Before notifyDataSetChanged(): " + recipes.size());
adapter.notifyDataSetChanged();
Log.d("CookbookFragment", "After notifyDataSetChanged(): " + recipes.size());
// Notify the adapter of the data change
}
// Close the cursor to avoid memory leaks
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
}
@Override
public void onResume() {
super.onResume();
Log.d("CookbookFragment", "onResume called");
// Check if data needs to be refreshed and refresh if necessary
// Example: storeDataInArrays();
}
@Override
public void onRecipeItemClick(MyRecipe recipe) {
// Handle the click event, e.g., open UpdateActivity with the selected recipe
Intent intent = new Intent(requireContext(), UpdateActivity.class);
intent.putExtra("recipe", recipe);
startActivity(intent);
}
public void refreshData() {
recipes.clear();
storeDataInArrays();
adapter.notifyDataSetChanged();
}
}
`
****CookbookAdpater class**
**
public class CookbookAdapter extends RecyclerView.Adapter<CookbookAdapter.ViewHolder> {
public interface RecipeItemClickListener {
void onRecipeItemClick(MyRecipe recipe);
}
private List<MyRecipe> recipes;
private RecipeItemClickListener itemClickListener;
// Constructor to initialize the adapter with a list of recipes
public CookbookAdapter(List<MyRecipe> recipes, RecipeItemClickListener itemClickListener) {
this.recipes = recipes;
this.itemClickListener = itemClickListener;
}
// ViewHolder class to hold references to the views within each item
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// Declare your views here (e.g., TextViews, ImageViews, etc.)
EditText editTextRecipeTitle;
EditText editTextIngredients;
EditText editTextInstructions;
EditText editTextTimeToCook;
// ImageView imageViewRecipe;
Button buttonCreateRecipe;
public ViewHolder(View itemView) {
super(itemView);
editTextRecipeTitle = itemView.findViewById(R.id.editTextRecipeTitle);
editTextIngredients = itemView.findViewById(R.id.editTextIngredients);
editTextInstructions = itemView.findViewById(R.id.editTextInstructions);
editTextTimeToCook = itemView.findViewById(R.id.editTextTimeToCook);
itemView.setOnClickListener(this);
// Initialize your views here
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
itemClickListener.onRecipeItemClick(recipes.get(position));
}
}
public void bind(MyRecipe recipe) {
editTextRecipeTitle.setText(recipe.getTitle());
editTextIngredients.setText(recipe.getIngredients());
editTextInstructions.setText(recipe.getInstructions());
editTextTimeToCook.setText(String.valueOf(recipe.getTimeToCook()));
}
}
// onCreateViewHolder to inflate the item layout and create the ViewHolder
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_row, parent, false);
return new ViewHolder(view);
}
// onBindViewHolder to bind data to the views within each item
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
MyRecipe recipe = recipes.get(position);
Log.d("CookbookAdapter", "Binding recipe at position " + position + ": " + recipe.getTitle());
// Log the contents of the recipe for additional verification
Log.d("CookbookAdapter", "Title: " + recipe.getTitle());
Log.d("CookbookAdapter", "Ingredients: " + recipe.getIngredients());
Log.d("CookbookAdapter", "Instructions: " + recipe.getInstructions());
Log.d("CookbookAdapter", "TimeToCook: " + recipe.getTimeToCook());
holder.bind(recipe);
}
@Override
public int getItemCount() {
return recipes.size();
}
}
**RecipeDatabase class:**
public class RecipeDatabase extends SQLiteOpenHelper {
private Context context;
private static final String DATABASE_NAME = "recipe_database";
private static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "my_recipes";
public static final String COLUMN_ID = "id";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_INGREDIENTS = "ingredients";
public static final String COLUMN_INSTRUCTIONS = "instructions";
public static final String COLUMN_TIME_TO_COOK = "time_to_cook";
public RecipeDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String query =
"CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_TITLE + " TEXT, " +
COLUMN_INGREDIENTS + " TEXT, " +
COLUMN_INSTRUCTIONS + " TEXT, " +
COLUMN_TIME_TO_COOK + " INTEGER)";
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addRecipeToDatabase(MyRecipe newRecipe) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// Add recipe details to the ContentValues
values.put(COLUMN_TITLE, newRecipe.getTitle());
values.put(COLUMN_INGREDIENTS, newRecipe.getIngredients());
values.put(COLUMN_INSTRUCTIONS, newRecipe.getInstructions());
values.put(COLUMN_TIME_TO_COOK, newRecipe.getTimeToCook());
long newRowId = db.insert(TABLE_NAME, null, values);
Log.d("RecipeDatabase", "addRecipeToDatabase: newRowId = " + newRowId);
//db.insert(TABLE_NAME, null, values);
// Close the database
newRecipe.setId(newRowId);
db.close();
return newRowId != -1;
// }
}
public Cursor readAllData() {
String query = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = null;
if (db != null) {
cursor = db.rawQuery(query, null);
}
return cursor;
}
public boolean updateRecipe(MyRecipe recipe) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// Add updated recipe details to the ContentValues
values.put(COLUMN_TITLE, recipe.getTitle());
values.put(COLUMN_INGREDIENTS, recipe.getIngredients());
values.put(COLUMN_INSTRUCTIONS, recipe.getInstructions());
values.put(COLUMN_TIME_TO_COOK, recipe.getTimeToCook());
return db.update(TABLE_NAME, values, COLUMN_ID + " = ?", new String[]{String.valueOf(recipe.getId())}) > 0;
}
public void deleteOneRow(MyRecipe recipe){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, COLUMN_ID + " = ?", new String[]{String.valueOf(recipe.getId())});
db.close();
}
}
```