如何通过Android Java中的ViewModel在ROOM数据库中通过ID检索数据

时间:2020-07-30 14:45:50

标签: java android android-room viewmodel android-livedata

我是android开发的新手,正在开发一个应用程序。在第一页中,它将显示您在recyclerview中添加的食谱的列表。然后,当您单击某个食谱时,它将带您到另一个页面,该页面显示该食谱的成分,该页面也在recyclerview中,并且具有CRUD功能和顶部的搜索栏。

我的问题是我无法根据其所属的食谱正确地检索这些成分。每当我单击一个配方时,它都包含与我为另一个配方创建的相同的成分。我能够正确地将配方ID传递到成分片段/页面,但无法弄清楚如何在ViewModel中使用它来获取正确的成分

这是我的“成分”页面代码:

-IngredientFragment

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {

    // this will set the lastMenuItemSelected for the navigation to work properly
    ((MainActivity)getActivity()).setLastMenuItemSelected(R.id.navigation_ingredient);

    mIngredientViewModel = new ViewModelProvider(getActivity()).get(IngredientViewModel.class);
    root = inflater.inflate(R.layout.fragment_ingredient, container, false);
    textViewSchoolAvailable = root.findViewById(R.id.textViewIngredientAvailable);
    textViewRecipeName = root.findViewById(R.id.textViewRecipeName);


    // recycleview
    RecyclerView recyclerView = root.findViewById(R.id.recyclerview);
    final IngredientListAdapter adapter = new IngredientListAdapter(mIngredients, this);
    new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    textViewRecipeName.setText(getArguments().getString("recipeName"));

    mIngredientViewModel.setFilter("");

    mIngredientViewModel.getAllIngredients().observe(getActivity(), new Observer<List<Ingredient>>() {
        @Override
        public void onChanged(@Nullable final List<Ingredient> Ingredients) {
            // Update the cached copy of the Ingredients in the adapter.
            if (!Ingredients.isEmpty()) {
                textViewSchoolAvailable.setVisibility(View.GONE);
                adapter.setIngredients(Ingredients);
                mIngredients = Ingredients;
                //Toast.makeText(getActivity(),"testing!",Toast.LENGTH_SHORT).show();
            } else
                textViewSchoolAvailable.setVisibility(View.VISIBLE);
                adapter.setIngredients(Ingredients);
                mIngredients = Ingredients;

            }
        });

    TextView textInputSearch = root.findViewById(R.id.textInputSearch);

    textInputSearch.setOnKeyListener( new View.OnKeyListener() {
        @Override
        public boolean onKey( View v, int keyCode, KeyEvent event ) {
            if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
                mIngredientViewModel.setFilter("%"+textInputSearch.getText()+"%");
            }
            return false;
        }
    });

成分视图模型:

在这一部分中,我正在考虑一种将配方ID传递给mRepository.getAllIngredients()的方法,因此它将仅返回具有该ID的配料,我的想法是在这一部分传递第二个参数{{1} }像Transformations.switchMap(filterText, (input) ->一样,但是它不起作用,我也为Transformations.switchMap(filterText, (input, recipeId) ->苦苦挣扎,因为这部分是用于搜索栏的,我也应该在此处传递配方ID,但是它只有一个参数用户输入的搜索词,因此当用户搜索时,它将获得所有成分,而不管其属于哪个食谱。

mRepository.filter(input);

成分库:

public class IngredientViewModel extends AndroidViewModel {

 private IngredientRepository mRepository;

    private LiveData<List<Ingredient>> mAllIngredients;

    private MutableLiveData<String> filterText = new MutableLiveData<>();

    public IngredientViewModel (Application application) {
        super(application);
        mRepository = new IngredientRepository(application);
        //mAllIngredients = mRepository.getAllIngredients();

        mAllIngredients = Transformations.switchMap(filterText, (input) ->
        {
            if(input == null || input.equals(""))
                return mRepository.getAllIngredients();
            else
                return mRepository.filter(input);
        });
    }

    public void setFilter(String query) {

        filterText.setValue(query);
    }

    public LiveData<List<Ingredient>> getAllIngredients() {

        return mAllIngredients;

    }

DAO成分:

public class IngredientRepository {

   private IngredientDAO mIngredientDao;
    private LiveData<List<Ingredient>> mAllIngredients;

    public IngredientRepository(Application application) {
        RecipeRoomDatabase db = RecipeRoomDatabase.getDatabase(application);
        mIngredientDao = db.ingredientDAO();
        mAllIngredients = mIngredientDao.getAllIngredients();
    }

    public LiveData<List<Ingredient>> filter(String input) {
        try {
            return new FilterIngredientAsyncTask(mIngredientDao).execute(input).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static class FilterIngredientAsyncTask extends AsyncTask<String, Void, LiveData<List<Ingredient>>> {
        private IngredientDAO ingredientsDAO;

        private FilterIngredientAsyncTask(IngredientDAO ingredientsDAO) {
            this.ingredientsDAO = ingredientsDAO;
        }

        @Override
        protected LiveData<List<Ingredient>> doInBackground(String... strings) {
            return ingredientsDAO.filter(strings[0]);
        }
    }

    public LiveData<List<Ingredient>> getAllIngredients() {
        return mAllIngredients;
    }

对我来说,检索食谱中所有成分以及过滤器部件的最佳方法是什么? 非常感谢!

0 个答案:

没有答案