I hope the diagram above gives a rough idea of the current design hierarchy of my app. MainFragment shows the current account level of the user. There is a progression map with each section containing a list of tasks. User clicks a section, task list is displayed. For example, such task is to watch a video in its entirety. Once that's done, a level up dialog is displayed which is acknowledged by the user with a button click. The user is then returned to MainFragment with an update of the account level.
I created a test app beforehand to understand the basic functionality of ActivityResultLauncher since startActivityResult is now deprecated. The test app is a little different than the diagram for which instead of a fragment calling TaskList, it is an activity. It worked well nonetheless.
So now I am implementing it in my main project. The issue I am having is that while the launcher works correctly to launch the activity for a task, the onActivityResult in MainFragment is not being called. Is there something that I missed out?
Here is the ActivityResultLauncher code I am using in MainFragment. It is placed as a global variable.
ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == VideoViewer.RESULT_OK) {
// Level Up
int level = result.getData().getIntExtra("level", 0);
Toast.makeText(activity, "LEVEL UP! :D" + level + 1, Toast.LENGTH_SHORT).show();
Log.i(TAG, "onActivityResult: Called");
}
}
});
I then pass the launcher as a parameter into TaskListDialogFragment like so
TaskListDialog taskListDialog = new TaskListDialog(taskItemList.get(0), level, launcher);
taskListDialog.show(fm, "tasklist");
In TaskListDialog
// Constructor
public TaskListDialog(TaskItem taskItem, int level, ActivityResultLauncher<Intent> launcher) {
this.taskItem = taskItem;
this.level = level;
this.launcher = launcher;
}
// Launch Intent section
Intent watchVideo = new Intent(TaskListDialog.this.getActivity(), VideoViewer.class);
watchVideo.putExtra("media", response.body());
launcher.launch(watchVideo);
In VideoViewer
// onButtonClick is from DialogListener Interface
@Override
public void onButtonClick() {
// Task done. Return to MainFragment
Intent levelReturn = new Intent();
levelReturn.putExtra("level", accountLevel);
setResult(VideoViewer.RESULT_OK, levelReturn);
finish();
}
private void levelUp(int level) {
FragmentManager fm = getSupportFragmentManager();
LevelUpDialog levelUpDialog = new LevelUpDialog("Level Up!", level, taskItem);
levelUpDialog.show(fm, "fragment_level_up");
}
In LevelUpDialog
public interface DialogListener {
void onButtonClick();
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// User acknowledges level up. Dismiss and return to MainFragment
DialogListener dialogListener = (DialogListener) getActivity();
assert dialogListener != null;
dialogListener.onButtonClick();
dismiss();
}
});
EDIT UPDATE As stated in my comment reply, I missed out on an important difference between the test app and main project. The test app flow is Activity > DialogFragment > VideoViewer. Main project flow is Fragment > DialogFragment > PreviewActivity > VideoViewer. It worked when I removed PreviewActivity from the flow. However, I would like for the user to preview the task before doing it. I suppose the issue now is how can I retrieve the activity result after passing through multiple activities.
