为什么数据保存到我的房间数据库时我的RecyclerView没有更新?

问题描述 投票:0回答:1

我正在尝试创建一个食谱守护者应用程序,它能够将食谱存储到房间数据库中,并使用回收器视图将它们显示在主家庭片段上。每次我向数据库中添加内容时,它都不会更新回收器视图,除非我关闭应用程序并再次打开它。当我这样做时,就会出现新条目。我该如何解决这个问题?

这是我的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;
    }
java android database android-recyclerview
1个回答
0
投票

Room 不会自动发布更改,您需要使用某种可观察类型,例如 Kotlin

Flow
或 RxJava
Observable

请参阅:https://developer.android.com/training/data-storage/room/async-queries#options

© www.soinside.com 2019 - 2024. All rights reserved.