android - after orrientation change target fragment changes in dialog fragment
Asked Answered
S

4

6

I have a fragment which adds an option to the option menu. When this option is clicked a dialog fragment opens. The dialog has the original fragment set to its target fragment. If no orientation change happens while the dialog fragment is open the target fragment is as expected but after orientation change the target fragment is set to the dialog fragment itself instead of the fragment which was set previously. As a result I get a classCastException when trying to cast the target fragment to the fragment which was set as the target fragment. I need to get the target fragment in my dialog because it implements a callback (OnStartOrRestartLoader). I've been trying to solve this issue for over a week and would really appreciate if somebody could point me in the right direction. Since this is my first question here I apologize if I've excluded some necessary information or if this is not an appropriate question here.

In the fragment (VirsārstsFragment) which implements OnStartOrRestartLoader I create the dialog as follows:

FragmentManager fm = getChildFragmentManager();
SearchDialogFragment dialog = new SearchDialogFragment();
dialog.show(fm, "searchDialog");
dialog.setTargetFragment(this, DIALOGFRAGMENT);

Then in the SearchDialogFragment I do the following to set the callback:

OnStartOrRestartLoader callback = (OnStartOrRestartLoader) getTargetFragment();

Logcat:

08-25 12:15:55.087: E/AndroidRuntime(10057): FATAL EXCEPTION: main
08-25 12:15:55.087: E/AndroidRuntime(10057): Process: com.example, PID: 10057
08-25 12:15:55.087: E/AndroidRuntime(10057): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.ClassCastException: com.example.SearchDialogFragment cannot be cast to com.example.OnStartOrRestartLoader
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2224)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2273)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3759)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.access$900(ActivityThread.java:141)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1208)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.os.Handler.dispatchMessage(Handler.java:102)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.os.Looper.loop(Looper.java:136)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.main(ActivityThread.java:5052)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at java.lang.reflect.Method.invokeNative(Native Method)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at java.lang.reflect.Method.invoke(Method.java:515)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at dalvik.system.NativeStart.main(Native Method)
08-25 12:15:55.087: E/AndroidRuntime(10057): Caused by: java.lang.ClassCastException: com.example.SearchDialogFragment cannot be cast to com.example.OnStartOrRestartLoader
08-25 12:15:55.087: E/AndroidRuntime(10057):    at com.example.SearchDialogFragment.onCreateDialog(SearchDialogFragment.java:59)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:307)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1901)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1518)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:962)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1901)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:567)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.Activity.performStart(Activity.java:5322)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2187)
08-25 12:15:55.087: E/AndroidRuntime(10057):    ... 13 more
Skein answered 25/8, 2014 at 9:24 Comment(5)
can you post more codeLittrell
Does your UI change on orientation change? I mean do you have a different UI to be shown for each orientation?Ileneileo
I don't get it. getTargetFragment() returns a Fragment and you are trying to cast it to OnStartOrRestartLoader. The exception is very clear. What are you trying to do?Riser
@Riser what you mentioned is true now that I think of it, but the same problem persists even if I try to cast to VirsārstsFragment which extendes Fragment. I found a solution by using getParentFragment instead of getTargetFragment.Recept
@Ileneileo the same UI. I add spinners and textviews programatically and want to retain their contents after rotation(that's working) when I click the positive button I need to restart the cursorLoader with new parameters in the parent fragment (works only if no orientation change).Recept
P
5

setTargetFragment should not be used to establish a relationship between parent/child fragments. It should only be used to link sibling fragments (i.e. those that exist within the same FragmentManager).

The reason it doesn't work between parent/child fragments is a fragment's target is saved and restored as an index into its own FragmentManager. So everything will be hunky dory until the framework restores an Activity after, for example, an orientation change. At that point the FragmentManager will look for the target fragment within itself instead of the parent FragmentManager.

Priestridden answered 11/5, 2017 at 0:52 Comment(0)
S
3

I don't still understand why exactly getTargetFragment() didn't work for me, but replacing it with getParentFragment() solved my issue.

Skein answered 25/8, 2014 at 13:52 Comment(1)
I also had to use getChildFragmentManager() instead of getFragmentManager() https://mcmap.net/q/413408/-getparentfragment-returning-nullDrizzle
J
0

This is super late but I ran into this today and thought I'd write down my solution in case someone needs it.

The problem here is you are passing the VirsārstsFragment's ChildFragmentManager to SearchDialogFragment.

FragmentManager fm = getChildFragmentManager();
SearchDialogFragment dialog = new SearchDialogFragment();
dialog.show(fm, "searchDialog");

Instead you need to pass the normal fragment manager (get it by using getFragmentManager()).

I think your code doesn't because on a restore because the System looks for VirsārstsFragment in childFrgamentManager you passed to SearchDialogFragment but can not find it since VirsārstsFragment is actually in the activity's fragment manager. Passing the Activity's fragment manager to SearchDialogFragment fixes this.

Jennee answered 18/3, 2019 at 14:52 Comment(0)
I
-4

In case there is no UI change you can add the property configChanges to the activity in manifest

<activity
        android:name=".YourActivity"
        android:configChanges="screenSize|orientation"/>

What this does is it specifies that configuration changes when screensize or orientation changes are handled in the activity itself (in your case there is no change so no need to do anything)

In case you need to handle any changes in future you can do that in onConfigurationChanged() in your activity.

Let me know if this works in your case

Ileneileo answered 27/8, 2014 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.