【问题标题】:Child fragment is destroying automatically子片段正在自动销毁
【发布时间】:2016-10-09 15:08:43
【问题描述】:

我有一个父片段,即FragmentA,并在其上膨胀了一个子片段FragmentB。在FragmentB 的 onCreateView 函数中试图膨胀另一个片段 `FragmentC'。

片段A.java

public class FragmentA extends Fragment {

    private static final String TAG = "FragmentA";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                 Bundle savedInstanceState) {
    /* Inflate the layout for this fragment */
    View view = inflater.inflate(R.layout.root_fragment, container, false);


    FragmentManager manager = getChildFragmentManager();

    FragmentTransaction transaction = manager
        .beginTransaction();
    /*
     * When this container fragment is created, we fill it with our first
         * "real" fragment
         */
    transaction.replace(R.id.container_main, new FragmentRecharge());
    transaction.addToBackStack(null);
    transaction.commit();


    return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
    outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
    super.onSaveInstanceState(outState);
    }
}

片段B.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.recharge_layout_new, container,

    false);
....

try {
    ((ActivityMain) context).bannerView.setVisibility(View.GONE);
    Fragment fragment = new FragmentC();
//                fragment.setArguments(bundle);
    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.container_main, fragment);
    fragmentTransaction.addToBackStack("my_fragment");
    fragmentTransaction.commit();
} catch (Exception e) {
    Crashlytics.logException(e);
}

 }  

FragmentC.java

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                 Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.recharge_layout_new, container,

    false);
    ....

布局文件:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/tools"
    android:id="@+id/parent_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/fragment_back_color">

     <FrameLayout
    android:id="@+id/container_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="visible">

    </FrameLayout>

but it get destroyed automatically and come to `FragmentB`.  How can I fix this issue ?

我正在尝试以 1 秒的间隔将 HandlerpostDelayed 一起使用,然后它正在膨胀 FragmentC 并且工作正常。这看起来不是解决方案。

        new android.os.Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    ((ActivityMain) context).bannerView.setVisibility(View.GONE);
                    Fragment fragment = new FragmentC();
//                fragment.setArguments(bundle);
                    FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    fragmentTransaction.add(R.id.container_main, fragment);
                    fragmentTransaction.addToBackStack("my_fragment");
                    fragmentTransaction.commit();
                } catch (Exception e) {
                    Crashlytics.logException(e);
                }
            }
        }, 1000);

【问题讨论】:

  • 我一直在寻找它,但那不是我的情况。
  • 那么 FragmentC 和 FragmentB 是 FragmentA 的子代?
  • 无法复制您的问题。如果您可以共享您的整个代码,那就太好了。
  • 是的。FragmentB 和 FragmentC 是 fragmentA 的子代。

标签: android android-fragments fragment android-nested-fragment


【解决方案1】:

我以我的方式做到了,它没有破坏片段 C,它工作正常。

TestFragmentActivity.java

public class TestFragmentActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_test);

        FragmentA fragmentA = new FragmentA();
        FragmentTransaction mTransaction = getSupportFragmentManager().beginTransaction();
        mTransaction.replace(R.id.container_main, fragmentA).commit();
    }

}

FragmentA.java

public class FragmentA extends Fragment
{
    View view;

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

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);

        FragmentB fragmentB = new FragmentB();
        FragmentTransaction mTransaction = getChildFragmentManager().beginTransaction();
        mTransaction.replace(R.id.xLinLayFragmentContentB, fragmentB).commit();

    }
}

FragmentB.java

public class FragmentB extends Fragment
{
    View view;

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

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);

        FragmentC fragmentC = new FragmentC();
        FragmentTransaction mTransaction = getChildFragmentManager().beginTransaction();
        mTransaction.replace(R.id.xLinLayFragmentContentC, fragmentC).commit();
    }
}

FragmentC.java

public class FragmentC extends Fragment
{
    View view;

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

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);


    }
}

activity_fragment_test.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/parent_layout"
                xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:card_view="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/container_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible">

    </FrameLayout>

</RelativeLayout>

fragment_a.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center"
              android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment A"
        android:textSize="15sp"/>

    <LinearLayout
        android:id="@+id/xLinLayFragmentContentB"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:orientation="vertical"/>

</LinearLayout>

fragment_b.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center"
              android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment B"
        android:textSize="15sp"/>

    <LinearLayout
        android:id="@+id/xLinLayFragmentContentC"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:orientation="vertical"/>

</LinearLayout>

fragment_c.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center"
              android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment C"
        android:textSize="15sp"/>


</LinearLayout>

【讨论】:

    【解决方案2】:

    您应该像这样在 onActivityCreated() 方法中调用嵌套片段。

    @Override
        public void onActivityCreated(Bundle savedInstanceState)
        {
            super.onActivityCreated(savedInstanceState);
            Fragment fragment = new FragmentC();
        //                  fragment.setArguments(bundle);
                        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                        fragmentTransaction.add(R.id.container_main, fragment);
                        fragmentTransaction.addToBackStack("my_fragment");
                        fragmentTransaction.commit();
    }
    

    【讨论】:

      【解决方案3】:

      尝试默认实现 onDestroy(),如果你的片段中有 onAttach(),然后删除它,可能会产生问题。我正在使用这个片段调用来替换片段。试试这个。也许它会帮助你:

          Fragment mFragment = null;
                          mFragment = new RadarMainActivity();
                          FragmentManager fragmentManager = getActivity()
                                  .getSupportFragmentManager();
                          fragmentManager.beginTransaction()
                                  .replace(R.id.container_body, mFragment).commit();
      

      【讨论】:

        【解决方案4】:

        更新 我在 mi Github Account 中使用手动嵌套片段添加实现测试

        使用当前版本的 Android 支持,您可以通过 getChildFragmentManager() 嵌套片段。 childFragmentManager 背后的基础是它延迟加载,直到前一个片段事务完成。还有其他方法吗?

        当然!没有 ChildManager 的嵌套,但是如何嵌套呢?好吧,见下文; 我们将有一个延迟的 Fragment,它会延迟加载,因此可以在其中加载其他 Fragment。

        这个想法很简单。但是,Handler 是要找到一个非常方便的类,在当前 Fragment 事务完成提交后,在主线程上有效地等待空间执行(Fragments 会干扰 UI,因此它们在主线程上运行)。

        private final Handler handler = new Handler();
        private Runnable runPager;
        
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            return inflater.inflate(R.layout.recharge_layout_new, container, false);
        }
        
        @Override
        public void onActivityCreated(Bundle savedInstanceState)
        {
            super.onActivityCreated(savedInstanceState);
            runPager = new Runnable() {
        
                @Override
                public void run()
                {
                  getFragmentManager().beginTransaction().addFragment(R.id.frag_container, FragmentC.newInstance()).commit();
                }
            };
            handler.post(runPager);
        }
        
        /**
         * @see android.support.v4.app.Fragment#onPause()
         */
        @Override
        public void onPause()
        {
            super.onPause();
            handler.removeCallbacks(runPager);
        }
        

        【讨论】:

        • 不工作。同样的片段破坏问题。我在 onActivityCreated() 函数中使用过。
        • 让我想另一种解决方案来防止片段被破坏。你有你onActivityCreated()的代码吗?
        • 我更新了帖子,有一个基于手动添加嵌套片段的示例。这是链接:github.com/teocci/NestedFragments
        猜你喜欢
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        相关资源
        最近更新 更多