子片段正在自动销毁

Posted

技术标签:

【中文标题】子片段正在自动销毁【英文标题】: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_
    android:layout_
    android:background="@color/fragment_back_color">

     <FrameLayout
    android:id="@+id/container_main"
    android:layout_
    android:layout_
    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);

【问题讨论】:

可能重复:***.com/questions/15203766/… 我一直在寻找它,但那不是我的情况。 那么 FragmentC 和 FragmentB 是 FragmentA 的子代? 无法复制您的问题。如果您可以共享您的整个代码,那就太好了。 是的。FragmentB 和 FragmentC 是 fragmentA 的子代。 【参考方案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_
                android:layout_>

    <FrameLayout
        android:id="@+id/container_main"
        android:layout_
        android:layout_
        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_
              android:layout_
              android:gravity="center"
              android:orientation="vertical">

    <TextView
        android:layout_
        android:layout_
        android:text="Fragment A"
        android:textSize="15sp"/>

    <LinearLayout
        android:id="@+id/xLinLayFragmentContentB"
        android:layout_
        android:layout_
        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_
              android:layout_
              android:gravity="center"
              android:orientation="vertical">

    <TextView
        android:layout_
        android:layout_
        android:text="Fragment B"
        android:textSize="15sp"/>

    <LinearLayout
        android:id="@+id/xLinLayFragmentContentC"
        android:layout_
        android:layout_
        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_
              android:layout_
              android:gravity="center"
              android:orientation="vertical">

    <TextView
        android:layout_
        android:layout_
        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

以上是关于子片段正在自动销毁的主要内容,如果未能解决你的问题,请参考以下文章

共享元素转换在父片段和子片段之间不起作用(嵌套片段)

隐藏子屏幕/片段的android底部导航视图

如何在销毁活动之前在视图寻呼机内的片段中执行某些操作

访问片段的子视图时出现空指针异常

如何防止应用重启后自动创建子片段?

Android:将 savedInstanceState 与片段一起使用