【问题标题】:Fragment methods: attach(), detach(), remove(), replace(), popBackStack()片段方法:attach()、detach()、remove()、replace()、popBackStack()
【发布时间】:2012-08-22 15:50:09
【问题描述】:

我对这些功能及其用途感到很困惑。我观察到使用replace() 将现有片段替换为新片段。我们可以使用addToBackStack(null) 将该片段放入回栈中,这样我们就可以回到之前显示的片段。现在,当添加(或替换)片段时 - onAttach() -> onCreate() 等......按顺序调用片段的方法。

现在,当我们从我们的活动中调用片段上的remove() 时,片段的哪些函数被调用以及以什么顺序调用?

attach()detach() 有什么作用? detach() 会删除片段吗?而这两个attach()detach()在使用时,分别调用了fragment的哪些函数,按什么顺序调用??

另外,popBackStack() 会发生什么??我的意思是当我们在活动的片段上使用popBackStack()时调用了哪些函数??

onDestroy() 什么时候调用??

谢谢。

【问题讨论】:

    标签: android android-fragments fragment back-stack


    【解决方案1】:

    现在,当我们从我们的活动中调用片段的 remove() 时,片段的哪些函数被调用以及以什么顺序被调用?

    http://developer.android.com/reference/android/app/Fragment.html

    顺序为:onPause()onStop()onDestroyView()onDestroy()onDetach()

    attach() 和 detach() 有什么作用? detach() 会删除片段吗?而当使用这两个attach()和detach()时,会调用fragment的哪些函数,调用顺序是什么??

    attach()detach() 分别将FragmentActivity 关联或分离。附加Fragment时调用onAttach()生命周期方法,分离时调用Fragment中的onDetach()生命周期方法。有关更多信息,请查看上面的链接。

    另外,popBackStack() 会发生什么?我的意思是当我们在活动的片段上使用 popBackStack() 时会调用哪些函数??

    如果Fragment 没有被销毁,则在popBackStack() 上调用onStart()onResume() 方法。如果Fragment 之前已被销毁,则生命周期方法将从onAttach() 开始调用。与在Activities 上按下返回按钮时相同。

    【讨论】:

    • “在 popBackStack() 上调用 onStart() 和 onResume() 方法”。这怎么可能???我们正在弹出片段,而不是添加它。
    • 当您弹出 backstack 时,这意味着您删除了当前片段,并将其替换为前一个片段,前一个片段存储在 backstack 中。
    • 你从后台弹出片段,而不是从屏幕中弹出。它是addToBackStack() 的对应物。
    • @Tapirboy 实际上已经 2 年了,所以我已经想出了办法:D
    • 关于 attach() 和 detach() 的答案是不正确。调用detach() 保持片段附加到活动,因此onDetach() 调用,但它分离其视图层次结构,因此onPause()onStop()onDestroyView() 被依次调用。调用attach()要求片段处于分离视图状态,并将其恢复正常状态,依次调用:onCreateView()onActivityCreated()onStart()onResume()
    【解决方案2】:

    请注意popBackStack()。它不会弹出一个片段,它会弹出一个片段事务。因此,无论最后一个片段交易是什么,都会被逆转。如果您显示的是 FragmentA 并且您的交易是:

    fragmentTransaction.replace(R.id.your_layout, fragmentB);
    fragmentTransaction.addToBackStack(null);
    

    它将用FragmentB 替换FragmentA,并将该事务(不是片段)添加到后台堆栈。如果您然后点击返回按钮,它会弹出返回堆栈并获取事务,即“用FragmentB 替换这个FragmentA”。然后它会撤销该交易。向后,该指令是用FragmentA 替换当前片段的任何内容。如果原来的FragmentA 仍然存在,它会使用那个。如果它被破坏了,它会重新生成一个。

    【讨论】:

      【解决方案3】:

      假设通过以下步骤将片段 A 和片段 B 添加到容器中:

      1. Added fragment A =>  .replace(R.id.container, fragmentA) => addToBackStack(null)
      2. Added fragment B =>  .replace(R.id.container, fragmentB) => addToBackStack(null)
      3. Removed fragment B => fragmentManager.popBackStack();
      

      调用 fm.popBackStack() 时的回调:

      FragmentB: onPause()
      FragmentB: onStop()
      FragmentB: onDestroy()
      FragmentB: onDetach()
      FragmentA: onCreateView()
      FragmentA: onViewCreated()
      FragmentA: onActivityCreated()
      FragmentA: onStart()
      FragmentA: onResume()
      

      解释:为什么在使用 popBackStack() 删除和销毁片段 B 时,片段 A 视图被再次创建并恢复?

      Ans:当你添加片段 B 时,你使用了 replace() 和 addToBackStack(),所以所有的片段都从容器中移除,片段 B 被添加到容器中。并且,此交易也记录在 Back 堆栈中。因此,当调用 fm.popBackStack() 时,首先将事务从返回堆栈中弹出,因此操作会自行恢复,因此片段 b 会从容器中删除并销毁。并且所有其他片段都被添加,因为我们的案例片段 A 的视图被添加到容器中。还注意到片段 A 的 onAttach & onCreate() 没有被调用,因为它之前已经被创建并附加到 MainActivity。

      在片段 B 上的后按做同样的事情:

      If you press the back button, it calls fm.popBackStack() and pops the transaction.
      

      【讨论】:

      • 但是当你回去或替换时它不会破坏片段我想?我以为它只是在后台暂停,不是吗?
      • 不,当你按下返回按钮时它被破坏了。
      猜你喜欢
      • 1970-01-01
      • 2013-05-17
      • 2014-11-13
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2014-12-18
      • 1970-01-01
      • 2014-06-23
      相关资源
      最近更新 更多