findFragmentByTag() returns null on existing fragmentTag

85
May 14, 2021, at 2:40 PM

I have an Activity with a FragmentContainer that will show only one of two Fragments.
By clicking on a Button of the first Fragment (CreateTasksListFragment), it is possible to show the other one (CreateTaskFragment).
When the user clicks on that button, CreateTasksListFragment gets hidden and a new instance of CreateTaskFragment is showed. Then, CreateTasksListFragment will be shown (by clicking on a button of CreateTaskFragment), and CreateTaskFragment has to be deleted.
The problem is that when I try to get the last instance of CreateTasksListFragment from the FragmentManager to show it again, even if I got its tag correctly by calling getBackStackEntryAt(), findFragmentByTag() returns null.
I don't think there're pending transactions, so probably I'm making another kind of mistake.
If you know better ways to achieve this goal, even without using this approach, please share them.

Here's the code interested by the issue:

CreateTasksActivity.java

@Override
protected void onStart() {
    super.onStart();
    Bundle bundle = new Bundle();
    ...
    CreateTasksListFragment fragment = new CreateTasksListFragment();
    fragment.setArguments(bundle);
    setCurrentFragment(fragment, CreateTasksListFragment.TAG);
}
/**
 * Sets new fragment
 * @param fragment
 */
public void setCurrentFragment(Fragment fragment, String fragmentTag){
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.create_tasks_fragment_container, fragment)
            .addToBackStack(fragmentTag)
            .commit();
}

CreateTasksListFragment.java

mNewTaskFabButton.setOnClickListener(v -> {
    Task task = new Task(mTasks.size() + 1);
    mTasks.add(task);
    Bundle bundle = new Bundle();
    bundle.putParcelable(CreateTaskFragment.TASK_EXTRA, task);
    CreateTaskFragment fragment = new CreateTaskFragment();
    fragment.setArguments(bundle);
    // Replacing fragment with the fragment to create a single task
    getParentFragmentManager()
            .beginTransaction()
            .hide(CreateTasksListFragment.this)
            .add(R.id.create_tasks_fragment_container, fragment)
            .addToBackStack(null)
            .commit();
});

CreateTaskFragment.java

mCreateTaskButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ...
        FragmentManager fm = getParentFragmentManager();
        Fragment fragment;
        String fragmentTag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2).getName(); // -2 since it starts counting from 0 and we need the second-last transaction
        Log.d("log1", fragmentTag);
        fragment = fm.findFragmentByTag(fragmentTag);
        Log.d("log2", String.valueOf(fragment == null));
        fm.beginTransaction()
                .remove(CreateTaskFragment.this)
                .show(fragment)
                .commit();
    }
});

Log

2021-05-13 21:19:44.952 20865-20865/* D/log1: CreateTasksListFragmentTag
2021-05-13 21:19:44.952 20865-20865/* D/log2: true

The tag is the same I've used when I put the first transaction on the backstack.

Answer 1

The name you get back from fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2).getName() is the name, you passed to addToBackStack(String name). That's an entirely separate concept from the tag associated with a fragment.

If you want to set a tag associated with a fragment, you need to set one as part of your replace() call using the version that takes a tag:

getSupportFragmentManager().beginTransaction()
        .replace(R.id.create_tasks_fragment_container, fragment, fragmentTag)
        .addToBackStack(fragmentTag)
        .commit();

Note: you should never mix a fragments transactions that use addToBackStack() with transactions that do not use addToBackStack() as this will break the behavior of popBackStack() and the system back button (which assumes you have not changed any of the fragments since the last addToBackStack() transaction).

READ ALSO
Showing message after redirect

Showing message after redirect

I'm trying to show a message after a successful redirect in my project, but can't find a really good way to do soRight now I have a very simple and not really good solution which looks like this:

14
Tabula py with Pycharm is not giving any output

Tabula py with Pycharm is not giving any output

I am trying to extract pdf tables using tabula py on pycharm

73
Cannot POST /admin Error return in web browser

Cannot POST /admin Error return in web browser

I want to update my images on the blog pagebut I got an error in the web browser like

60