关键android:target_state不再存在片段

时间:2015-04-18 07:43:52

标签: android android-layout android-fragments android-activity

我认为我有同样的问题here,但没有答案。

我有一个带有ViewPager的Activity和一个包含Fragment的FrameLayout。它看起来像这样:

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

旋转设备时。我会收到此错误:

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)

如果我不调用fragmentC.setTargetFragment方法或者我没有为Viewpager设置适配器,那么一切正常。 这是我的代码:

活动:

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();
        }
    }

}

活动布局:

 <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>

和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布局:

<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>

我知道我可以通过让Activity实现MyFragmentC.CallBack而不是FragmentB来实现它。 但我只是好奇为什么会发生??? 如果我没有为viewpager设置适配器,或者没有调用&#34; setTargetFragment&#34;在FragmentC中。一切都很好。

很抱歉,因为我不知道如何在这里很好地格式化代码,这是一个很长的帖子。任何帮助都可以升值。

2 个答案:

答案 0 :(得分:11)

请查看谷歌的讨论主题,建议他们删除setTargetFragment(),而不是使用getParentFragment()。这里提供了更多细节:https://code.google.com/p/android/issues/detail?id=54520

答案 1 :(得分:0)

我认为这是关于你的适配器中的getItem()方法。而不是使用FragmentPagerAdapter,您可以使用FragmentStatePagerAdapter并对getItem方法进行if检查。暂停和恢复后(在您的情况下这是方向更改)可能您对对象的引用会丢失。

在谷歌开发论坛中,他们也说不使用setTargetFragment方法,因为它有错误,你可以尝试使用getParentFragment。