子片段正在自动销毁
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 秒的间隔将 Handler
与 postDelayed
一起使用,然后它正在膨胀 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以上是关于子片段正在自动销毁的主要内容,如果未能解决你的问题,请参考以下文章