Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment no longer exists for key android:target_state

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

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

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

When I rotate the device. I 'll 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 work fine if I don't call fragmentC.setTargetFragment method or I don't set the Adapter for the Viewpager. Here are 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();
        }
    }

}

The Activity layout :

 <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's 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's 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's Fragment C" />

</LinearLayout>

I know that I can work around by let the Activity implement the MyFragmentC.CallBack instead of FragmentB implement it. But I just curious why does it happen ??? If I don't set Adapter for the viewpager or don't call "setTargetFragment" in FragmentC. Then everything work fine.

So sorry because I don't know how to format the code well in here and it's a long post. Any help could be appreciate.

like image 552
gZerone Avatar asked Oct 24 '25 05:10

gZerone


1 Answers

Please have a look into google's discussion thread where they are suggested to remove setTargetFragment() and instead use getParentFragment(). More detail is provided here : https://code.google.com/p/android/issues/detail?id=54520

like image 71
Smeet Avatar answered Oct 26 '25 19:10

Smeet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!