0

I try to use setTargetFragment in FragmentStateAdapter in the following manner.

public class SmartFragmentStateAdapter extends FragmentStateAdapter {
    private final SmartBarDialogFragment smartBarDialogFragment;

    public SmartFragmentStateAdapter(SmartBarDialogFragment smartBarDialogFragment) {
        super(smartBarDialogFragment);
 
        this.smartBarDialogFragment = smartBarDialogFragment;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        if (position == 0) {
            SmartColorFragment smartColorFragment = SmartColorFragment.newInstance(
                    smartBarDialogFragment.getSmartColors(),
                    smartBarDialogFragment.getSelectedColor()
            );

            smartColorFragment.setTargetFragment(
                    smartBarDialogFragment,
                    smartBarDialogFragment.getTargetRequestCode()
            );

            return smartColorFragment;
        }

I am getting the following runtime error by using smartBarDialogFragment.getParentFragmentManager().

java.lang.IllegalStateException: Fragment SmartColorFragment{dae5c36} (c3bf9012-c5e4-4e61-9756-02d2ac4fe9ea) f0} declared target fragment SmartBarDialogFragment{b19e737} (65b42f6c-381f-4000-9f2c-2d8c93a6af09) SMART_BAR_DIALOG_FRAGMENT} that does not belong to this FragmentManager!


super(smartBarDialogFragment); is using fragment.getChildFragmentManager().

Based on Fragment declared target fragment that does not belong to this FragmentManager

I try to fix it by modifying

public class SmartFragmentStateAdapter extends FragmentStateAdapter {
    private final SmartBarDialogFragment smartBarDialogFragment;

    public SmartFragmentStateAdapter(SmartBarDialogFragment smartBarDialogFragment) {
        // https://stackoverflow.com/questions/47045788/fragment-declared-target-fragment-that-does-not-belong-to-this-fragmentmanager
        super(smartBarDialogFragment.getParentFragmentManager(), smartBarDialogFragment.getLifecycle());

        this.smartBarDialogFragment = smartBarDialogFragment;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        if (position == 0) {
            SmartColorFragment smartColorFragment = SmartColorFragment.newInstance(
                    smartBarDialogFragment.getSmartColors(),
                    smartBarDialogFragment.getSelectedColor()
            );

            smartColorFragment.setTargetFragment(
                    smartBarDialogFragment,
                    smartBarDialogFragment.getTargetRequestCode()
            );

It works fine during dialog launched.

But, when I perform rotation, I am getting the error

java.lang.IllegalStateException: FragmentManager is already executing transactions

, with the following log detailed.

java.lang.IllegalStateException: FragmentManager is already executing transactions
    at androidx.fragment.app.FragmentManager.ensureExecReady(FragmentManager.java:1778)
    at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1814)
    at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297)
    at androidx.viewpager2.adapter.FragmentStateAdapter$FragmentMaxLifecycleEnforcer.updateFragmentMaxLifecycle(FragmentStateAdapter.java:726)
    at androidx.viewpager2.adapter.FragmentStateAdapter$FragmentMaxLifecycleEnforcer$3.onStateChanged(FragmentStateAdapter.java:657)
    at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
    at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
    at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
    at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
    at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
    at androidx.fragment.app.Fragment.performStart(Fragment.java:2735)
    at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
    at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
    at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
    at androidx.fragment.app.Fragment.performStart(Fragment.java:2739)
    at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
    at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
    at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
    at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:258)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:550)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1455)
    at android.app.Activity.performStart(Activity.java:8076)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3658)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2202)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7829)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:982)

Do you know, how to properly setTargetFragment for Fragment in FragmentStateAdapter, and able to handle rotation?

Cheok Yan Cheng
  • 48,324
  • 124
  • 436
  • 828
  • With your first case the adapter will be using `smartBarDialogFragment.getChildFragmentManager()` . So all your child fragment are now inside `ChildFragmentManager` of `smartBarDialogFragment` . So when you trying to find the parent Fragment Manger using the target fragment your should be using `getTargetFragment().getChildFragmentManager()` instead of `getParentFragmentManager` .. That's my cue let me know if i misunderstood the question .. – ADM Apr 06 '22 at 12:45

0 Answers0