我正在尝试创建一个食谱守护者应用程序,它能够将食谱存储到房间数据库中,并使用回收器视图将它们显示在主家庭片段上。每次我向数据库中添加内容时,它都不会更新回收器视图,除非我关闭应用程序并再次打开它。当我这样做时,就会出现新条目。我该如何解决这个问题?
这是我的homeFragment代码:
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代码:
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);
}
}
}
食谱型号代码:
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;
}
Room 不会自动发布更改,您需要使用某种可观察类型,例如 Kotlin
Flow
或 RxJava Observable
。
请参阅:https://developer.android.com/training/data-storage/room/async-queries#options