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?
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)