在片段事务

时间:2017-02-14 05:28:48

标签: android android-fragments fragment-lifecycle

我创建了一个演示,以了解在片段事务的不同情况下调用所有片段生命周期的方法。虽然大多数调用都是按照期望的,我仍然很困惑,我用Bold写的。

假设有两个片段A和B,我们正在它们之间执行交易

案例1

将片段B添加到片段A

getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, fragementB).addToBackStack(null).commit();

片段B

  

onAttach

     

的onCreate

     

onCreateView

     

onActivityCreated

     

在onStart

     

的onResume

没有调用片段A的生命周期方法。

我的期望是什么?

调用片段A的onStop方法,因为片段A不可见

根据文件 -

  

已停止 - 片段不可见。主持人的活动都是   停止或片段已从活动中删除但已添加   到后面的堆栈。停止的片段仍然存在(所有状态和   会员信息由系统保留)。但是,它不是   用户可见的时间更长,如果活动是,则会被杀死   杀死。

这是否意味着在同一活动中添加新片段时,不会调用当前片段的方法?

然后在Fragment B中使用popBackStack()

片段B

  

的onPause

     

的onStop

     

onDestroyView

     

的onDestroy

     

onDetach

没有调用片段A的生命周期方法

我的期望是什么?

片段A的onStart方法被调用,因为片段A现在可见

案例2

当片段B替换片段A

getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragementB).commit();

片段B

  

onAttach

     

的onCreate

     

onCreateView

     

onActivityCreated

     

在onStart

     

的onResume

片段A

  

的onPause

     

的onStop

     

onDestroyView

     

的onDestroy

     

onDetach

一切都符合预期

案例3

当片段B替换片段A时,将其保留在后台堆栈中

 getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragementB).addToBackStack("tag").commit();

片段B

  

onAttach

     

的onCreate

     

onCreateView

     

onActivityCreated

     

在onStart

     

的onResume

片段A

  

的onPause

     

的onStop

     

onDestroyView

片段A的onDestroy和onDetach方法未被调用。为什么不调用?Bcoz按照文档方法replace删除已经在容器中的所有片段并将新片段添加到同一个容器中

然后在Fragment B中使用popBackStack()

片段A

  

onCreateView

     

onActivityCreated

     

在onStart

     

的onResume

片段B

  

的onPause

     

的onStop

     

onDestroyView

     

的onDestroy

     

onDetach

3 个答案:

答案 0 :(得分:14)

  

这是否意味着在同一活动中添加新片段时不会调用当前片段的方法?

正确,您的第一个片段A只有在被移除或替换后才会受到影响(案例2)。 简单地添加另一个片段只会在片段A上显示片段B,并且不应该调用生命周期回调。

  

我的期望是什么?

     由于片段A现在可见,所以

片段A的onStart方法被调用

同样,由于片段B被添加到A之上,因此片段A不受B的去除影响。

  不调用片段A的onDestroy和onDetach方法。为什么不调用?Bcoz根据文档方法替换删除容器中已有的任何片段并将新的片段添加到同一个容器中

与简单替换不同,当您将替换事务添加到backstack时,实际上是将第一个片段附加到它的活动上,只会破坏其视图。

一旦你弹出backstack片段B被删除,片段A将只是重新创建它的视图 - 从onCreateView()开始。

答案 1 :(得分:1)

我运行一些日志以查看结果如下(就像在这里的活动中所做的一样:https://stackoverflow.com/a/61299029/3904109

片段开始

On Fragment Launched (First Time)
———————————————————————
onAttach: 
onCreateView:
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


On Coming Back To Fragment (From another fragment)
———————————————————————
onCreateView: 
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


OnMaximize(Square Button-After Back Pressed)
———————————————————————
onAttach: 
onCreateView: 
onViewCreated: 
onActivityCreated: 
onStart: 
onResume: 


OnMaximize(Square Button-After Circle Button)
———————————————————————
onStart: 
onResume:


OnMaximize(After Circle Button)
————————————————————————————————————————————————
onStart: 
onResume:

片段已停止

On Going To Another Fragment (Skipping 1 Fragment)
———————————————————————
onPause: 
onStop: 
onDestroyView: 


On BackPressed - Reverse Triangle Button (App Minimized)
———————————————————————
onPause: 
onStop: 
onDestroyView: 
onDestroy: 
onDetach: 


OnMinimize (Circle Button)
————————————————————————————————————————————————
onPause: 
onStop: 


OnMinimize (Square Button)
————————————————————————————————————————————————
onPause: 
onStop: 


Going To Another Activity
————————————————————————————————————————————————
onPause: 
onStop: 


Close The App
————————————————————————————————————————————————
onDestroyView: 
onDestroy:

如果有人要重新创建以检查以下代码:

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

    Log.d("TAG",
          "onCreateView: ");
}

@Override
public void onAttach(Context context) {
    Log.d("TAG",
          "onAttach: ");
    super.onAttach(context);
}

@Override
public void onViewCreated(@NonNull View view,
                          @Nullable Bundle savedInstanceState) {

    Log.d("TAG",
          "onViewCreated: ");
    super.onViewCreated(view,
                        savedInstanceState);
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    Log.d("TAG",
          "onActivityCreated: ");
    super.onActivityCreated(savedInstanceState);
}

@Override
public void onStart() {
    Log.d("TAG",
          "onStart: ");
    super.onStart();
}

@Override
public void onResume() {

    Log.d("TAG",
          "onResume: ");

    reAttachListeners();
    super.onResume();
}

@Override
public void onPause() {
    super.onPause();

    Log.d("TAG",
          "onPause: ");
    removeListeners();

}

@Override
public void onStop() {
    Log.d("TAG",
          "onStop: ");
    super.onStop();
}

@Override
public void onDestroyView() {
    Log.d("TAG",
          "onDestroyView: ");
    super.onDestroyView();
}

@Override
public void onDestroy() {
    Log.d("TAG",
          "onDestroy: ");
    super.onDestroy();
}

@Override
public void onDetach() {

    Log.d("TAG",
          "onDetach: ");
    super.onDetach();
}

答案 2 :(得分:0)

当片段可见或不可见

时,将调用

setUserVisibleHint