Fragment no longer exists for key android: target_state

I think I have the same problem here , but there is no answer.

I have an Activity with a ViewPager and FrameLayout that will contain a Fragment. It looks like this:

Activity
   |— ViewPager 
          |-FragmentA
   |— Framelayout 
        |— FragmentB
              |— FragmentC (here I called fragmentC.setTargetFragment method).

      

When I turn the device. I will get this error:

E/AndroidRuntime(10354): Caused by: java.lang.IllegalStateException: Fragment no longer exists for key android:target_state: index 1
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:586)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1118)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1922)
E/AndroidRuntime(10354):    at android.support.v4.app.Fragment.performCreate(Fragment.java:1776)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:915)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1118)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1922)
E/AndroidRuntime(10354):    at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:266)
E/AndroidRuntime(10354):    at com.example.android.animationsdemo.MyActivity.onCreate(MyActivity.java:20)

      

Everything works fine unless I call the fragmentC.setTargetFragment method, or I don't install the adapter for the Viewpager. Here is my code:

Activity:

public class MyActivity extends FragmentActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);

        TabsAdapter tabsAdapter = new TabsAdapter(this);
        mViewPager.setAdapter(tabsAdapter);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyFragmentB fragmentA = new MyFragmentB();
                getSupportFragmentManager().beginTransaction().add(R.id.flContainer, fragmentA,
                        "TAG").addToBackStack("back").commit();
            }
        });


    }

    public static class TabsAdapter extends FragmentPagerAdapter {

        private final Context mContext;
        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

        static final class TabInfo {
            private final Class<?> clss;
            private final Bundle args;

            TabInfo(Class<?> _class, Bundle _args) {
                clss = _class;
                args = _args;
            }
        }

        public TabsAdapter(FragmentActivity activity) {
            super(activity.getSupportFragmentManager());
            mContext = activity;

            TabInfo tabInfo = new TabInfo(MyFragmentA.class, null);
            mTabs.add(tabInfo);
        }

        @Override
        public Fragment getItem(int position) {
            TabInfo info = mTabs.get(position);
            return Fragment.instantiate(mContext, info.clss.getName(), info.args);
        }

        @Override
        public int getCount() {
            return mTabs.size();
        }
    }

}

      

Scheme of actions:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add Fragment B"/>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="300dip"
        android:id="@+id/flContainer" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:text="wrtadfa"/>
    </FrameLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_below="@+id/rlContainer"
        android:layout_width="match_parent"
        android:layout_height="300dip" />

</LinearLayout>

      

And FragmentA:

public class MyFragmentA extends Fragment {

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
        return myFragmentView;
    }
}

      

FragmentA layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >

   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="It Fragment A" />

</LinearLayout>

      

FragmentB:

public class MyFragmentB extends Fragment implements MyFragmentC.CallBack {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);

        myFragmentView.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyFragmentC fragmentA = new MyFragmentC();

                //This caused the problem
                fragmentA.setTargetFragment(MyFragmentB.this, 0);

                getChildFragmentManager().beginTransaction().add(R.id.flContainer2, fragmentA, "TAG").addToBackStack("back").commit();
            }
        });

        return myFragmentView;
    }
}

      

fragment_b.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#888888"
   android:orientation="vertical" >

   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="It Fragment B" />

   <TextView
       android:id="@+id/c_received"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add Fragment C"/>

    <FrameLayout
        android:id="@+id/flContainer2"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>
</LinearLayout>

      

FragmentC:

public class MyFragmentC extends Fragment {

    public static interface CallBack{
        //some call back
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        if(getTargetFragment() != null){
            CallBack callBack = (CallBack) getTargetFragment();
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View myFragmentView = inflater.inflate(R.layout.fragment_c, container, false);

        return myFragmentView;
    }
}

      

fragment_c.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#888888"
   android:orientation="vertical" >

   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="It Fragment C" />

</LinearLayout>

      

I know I can get around by letting Activity implement MyFragmentC.CallBack instead of FragmentB in order to implement it. But I'm just wondering why is this happening ??? Unless I set the adapter for the viewpager or call "setTargetFragment" in FragmentC. Then everything works fine.

So sorry because I don't know how to format the code here correctly and this is a long post. Any help could be appreciated.

+3


source to share


2 answers


Please take a look at the google discussion thread where it is suggested to remove setTargetFragment () and use getParentFragment () instead. More details are available here: https://code.google.com/p/android/issues/detail?id=54520



+11


source


I think this is for your getItem () method in your adapter. Instead, with FragmentPagerAdapter, you can use FragmentStatePagerAdapter and put an if check on your getItem method. After pausing and resuming (in your case, this is an orientation change), your object reference will probably be lost.



On the google dev forums they also say they don't use the setTargetFragment method since it's buggy, you can try using getParentFragment for that reason.

0


source







All Articles