Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Cannot be nested within a fragment #40

Closed
ened opened this Issue · 19 comments

5 participants

@ened

Given I add the CaldroidFragment into an existing fragment, I will receive this error message:

java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments

This is how I set things up:

@EFragment(R.layout.frg_analysis)
public class AnalysisFragment extends SherlockFragment {

    @AfterViews
    protected void setupView() {
        CaldroidFragment caldroidFragment = new CaldroidFragment();
        Bundle args = new Bundle();
        Calendar cal = Calendar.getInstance();
        args.putInt("month", cal.get(Calendar.MONTH) + 1);
        args.putInt("year", cal.get(Calendar.YEAR));
        caldroidFragment.setArguments(args);

        FragmentTransaction t = getChildFragmentManager().beginTransaction();
        t.add(R.id.containerCalendar, caldroidFragment);
        t.commit();
    }
}

Stackoverflow has some hints: http://stackoverflow.com/questions/14850573/cant-retain-nested-fragments .

Full stacktrace:

E/AndroidRuntime( 1763): java.lang.IllegalStateException: Can't retain fragements that are nested in other fragments
E/AndroidRuntime( 1763):    at android.support.v4.app.Fragment.setRetainInstance(Fragment.java:742)
E/AndroidRuntime( 1763):    at com.caldroid.CaldroidFragment.onCreate(CaldroidFragment.java:924)
E/AndroidRuntime( 1763):    at android.support.v4.app.Fragment.performCreate(Fragment.java:1437)
E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:877)
E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
E/AndroidRuntime( 1763):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
E/AndroidRuntime( 1763):    at android.support.v4.app.Fragment.performStart(Fragment.java:1481)
E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:941)
E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
E/AndroidRuntime( 1763):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
E/AndroidRuntime( 1763):    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
E/AndroidRuntime( 1763):    at android.os.Handler.handleCallback(Handler.java:725)
E/AndroidRuntime( 1763):    at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 1763):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 1763):    at android.app.ActivityThread.main(ActivityThread.java:5041)
E/AndroidRuntime( 1763):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1763):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 1763):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime( 1763):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime( 1763):    at dalvik.system.NativeStart.main(Native Method)
@thomasdao
Collaborator

Did you try to set API level more than Android 4.2?

@hackfrag

Nested fragments cannot have setRetainInstance(true)
I removed this line in the CaldroidFragment and now it works :)

@thomasdao
Collaborator

unfortunately if you remove that you cannot use it as dialog... The way Android handle the states quite messy :(

@ened

Yes, it's on both 4.2, 4.3 and 2.3 (target API is always latest, min API is 10). Both with support library and without.
We are using my fork now with the setRetainInstance call omitted (https://github.com/ened/Caldroid/tree/retain-instance).

@thomasdao I understand your point about the Dialog handling. Do you think the proposal from the SO link is helpful? Plus, starting from API 17 (and in recent support library) there is a method http://developer.android.com/reference/android/app/Fragment.html#getParentFragment(), which might be helpful to make the decision on whether to call setRetainInstance() or not?

@thomasdao
Collaborator

@ened: can clarify a bit more on what you want to achieve? I haven't tried Roboguice so I don't understand your code fully.

In my app, I can include Caldroid within other Fragment as well. Only difference is I extend android.support.v4.app.Fragment and using SherlockFragmentActivity

Your suggestion is useful but I need time to test it out. Android is not always straightforward :(

@ened

@thomasdao basically I'm using a fragment to present the UI to the user. The @AfterViews call is running just after onCreate is complete. Within the AnalysisFragment (inherits android.support.v4.app.Fragment now due to switch from ABS to ActionBarCompat) I'm simply adding the CaldroidFragment into the right place.

Maybe important: This is all done using the latest version of the compatibility library (r18).

@thomasdao
Collaborator

Can you try below code:

FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction t = fragmentManager.beginTransaction();
t.add(R.id.containerCalendar, caldroidFragment);
t.commit();
@ened

On a first try (running on 4.2), this works. Per http://developer.android.com/about/versions/android-4.2.html#NestedFragments I'm doing something that really should be done using the child fragment manager though.

@thomasdao
Collaborator

I'll try to support getChildFragmentManger, but in the mean time you can use getSupportFragmentManager instead. To support both dialog and embedded fragments, sometimes I run into weird issues with states.

@ened

Ok, thanks a lot for your help.

@thomasdao thomasdao closed this in 149da2c
@thomasdao thomasdao reopened this
@thomasdao
Collaborator

I found a simple way to fix this issue: just check if Caldroid is presented as dialog, and we only setRetainInstance(true) for dialog fragment. Pls let me know if it works for you :)

@thomasdao thomasdao closed this in acf244a
@natanloterio

I had the same problem.
change
FragmentTransaction t = getChildFragmentManager().beginTransaction();
to
FragmentTransaction t = getActivity().getSupportFragmentManager().beginTransaction();

@ambassajy

hello everyone. i tried to embed caldroid in my app, but i still get some errors in my mainactivity. i'm using android 4.3 : here t.replace(R.id.calendar1, caldroidFragment); eclipse suggests me to change type of caldroidFragment from DialogFragment to Fragment. . and here FragmentTransaction t = getActivity().getSupportFragmentManager().beginTransaction(); getActivity() is showed as an error. any help will be appreciated

@natanloterio

show your code, and also the error message plz

@ambassajy

thx for the quick reply, but i managed to solve the problem. this is how i fixed it: android.support.v4.app.FragmentTransaction t =
getSupportFragmentManager().beginTransaction();
t.replace(R.id.calendar1, caldroidFragment);

@ambassajy

but i have another issue. as i embed caldroid in my app, pls can u show me how to implement on date click so that i can pop up a dialog box when i click on any date, and how to sync the calendar to my database so that a date background color change according to some data in my database. thx in advance.

@ambassajy

sorry to bother again , but i dont know how to implement it: this is what i tried:
// Setup listener
listener = new CaldroidListener() {

        @Override
        public void onSelectDate(final Date date, View view) {
            Toast.makeText(getApplicationContext(), formatter.format(date),
                    Toast.LENGTH_LONG).show();

view.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    Toast.makeText(getApplicationContext(), formatter.format(date),
            Toast.LENGTH_LONG).show();
}

});
}

@thomasdao
Collaborator

Can you open new issue? It's quite hard to track. Btw to show dialog:

view.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Create a dialog here
        CaldroidFragment dialogCaldroidFragment = CaldroidFragment.newInstance("Select a date", 3, 2013);

       // Add a listener as per documentation
       final CaldroidListener listener = new CaldroidListener() {

           @Override
            public void onSelectDate(Date date, View view) {
                // You can perform your method on selected date
            }
       };

        dialogCaldroidFragment.setCaldroidListener(listener);

        // show the dialog
        dialogCaldroidFragment.show(getSupportFragmentManager(),"TAG");
    }
});

Btw I think it will be good for you in long term to slow down and understand Android fundamental and do not rush, you can do much faster later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.