Search code examples
javaandroidandroid-activityandroid-recyclerview

Update recyclerView Adapter on return to previous activity with newly created item


I'm working on an App to manage my workouts based on a room database.

Here I have a recyclerview with adapter for exercises in a workout. My current problem is that new exercises are not shown in the recyclerview after creating them and switching back to the workout-activity.

It seems like a quite easy topic (update recyclerview after returning from other activity) but I cant' get it working.

  • initial load of exercises at onCreate of workout-Activity:

    class GetExercises extends AsyncTask<Long, Void, List<Exercise>>{
    
          @Override
          protected List<Exercise> doInBackground(Long... params){
              if (params.length == 0 || params.length > 1) return null;
              return DatabaseClient
                      .getInstance(getApplicationContext())
                      .getAppDatabase().exerciseDao()
                      .getReferenced(params[0]);
          }
    
          protected void onPostExecute(List<Exercise> exerciseList){
              super.onPostExecute(exerciseList);
              rv_exercises.setAdapter(new Adapter_Exercise_RV(Activity_Workout_Edit.this, exerciseList));
          }
      }
    
  • creating a new exercise and returning the id to previous workout-activity:

    class CreateExercise extends AsyncTask<Void, Void, Void> {
          long id;
          @Override
          protected Void doInBackground(Void... voids) {
    
              Exercise ex = new Exercise();
              ex.setTitle(sTitle);
              ex.setSet(sSet);
              ex.setRep(sRep);
              ex.setAsTimer(bAsTimer);
    
              ex.setWorkoutId(workoutId);
    
              id = DatabaseClient.getInstance(getApplicationContext())
                  .getAppDatabase()
                      .exerciseDao()
                      .insertwithRet(ex);
              return null;
      }
    
          @Override
          protected void onPostExecute(Void aVoid) {
              super.onPostExecute(aVoid);
              finish(id);
              Toast.makeText(getApplicationContext(), "created new exercise", Toast.LENGTH_LONG).show();
          }
      }
      new CreateExercise().execute();
    
  • update adapter onActivityResult at workout-activity

    protected void onActivityResult(int requestCode, int resultCode, Intent data){
      super.onActivityResult(requestCode, resultCode, data);
      if(requestCode == 1 && resultCode == RESULT_OK){
          long exerciseId = (long) data.getExtras().get("exerciseId");
          rv_exercises.getAdapter().notifyDataSetChanged();
      }
    }
    

the exercise is created in the database, and after reopening the workout the new exercise is shown correctly. I do have a feeling that "notifyDataSetChanged" is not working, but can't find why?


Solution

  • The issue is that, in the next activity you are inserting an item to db, and returning its id but in onActivityResult, you do not add the item to the adapter, what you need to do is to fetch the item inserted to the DB, using the exerciseId, and then you add that item to the adapter and then you call to notify the adapter.

    protected void onActivityResult(int requestCode, int resultCode, Intent data){
      super.onActivityResult(requestCode, resultCode, data);
      if(requestCode == 1 && resultCode == RESULT_OK){
          long exerciseId = (long) data.getExtras().get("exerciseId");
          GetExerciseById(exerciseId).execute();
      }
    }
    

    Task to get the inserted entity

    class GetExerciseById extends AsyncTask<Long, Void, Exercise>{
    
         long exerciseId=0;
         GetExerciseById(long exerciseId){
           this.exerciseId=exerciseId;
         }
    
          @Override
          protected Exercise doInBackground(Long... params){
              if (this.exerciseId == 0) return null;
              return DatabaseClient
                      .getInstance(getApplicationContext())
                      .getAppDatabase().exerciseDao()
                      .getExcerciseById(exerciseId);
          }
    
          protected void onPostExecute(Exercise exercise){
              super.onPostExecute(exerciseList);
              if(exercise==null) return;//no item found with given id;
              if(rv_exercises.getAdapter() instanceof Adapter_Exercise_RV )
              {
                 Adapter_Exercise_RV adapter = (Adapter_Exercise_RV )rv_exercises.getAdapter();
                 adapter.addItem(exercise);
             }
          }
      }
    

    In your Adapter_Exercise_RV class

    void addItem(Exercise exercise){
      yourDatalist.add(exercise);
      notifyItemInserted(yourDatalist.size()-1);
    }
    

    In your DAO

    @Query("SELECT * FROM exercises WHERE workoutId:=exerciseId")//relative names and ids
    Exercise getExcerciseById(long exerciseId)