【问题标题】:What's the difference between detaching a Fragment and removing it?分离 Fragment 和删除它有什么区别?
【发布时间】:2026-01-24 15:55:01
【问题描述】:

FragmentTransaction 的Android 文档中,我注意到两个非常相似的方法:detachremove。那里的描述似乎没有提供关于何时使用每种方法的详细信息,据我所知,它们似乎是相同的。

那么:这两种方法有什么区别?

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    detach 方法从 UI 中移除片段,但其状态由片段管理器维护。这意味着您可以通过调用 attach 方法来重用这个片段,并使用修改后的 ViewHierarchy

    Remove 表示无法重新附加片段实例。您必须再次将其添加到片段事务中。

    来源评论

    您会注意到,当 Fragment 分离时,它的 onPause、onStop 和 onDestroyView 方法仅被调用(按此顺序)。另一方面,当一个 Fragment 被移除时,它的 onPause、onStop、onDestroyView、onDestroy 和 onDetach 方法会被调用(按顺序)。同样,在附加时,Fragment 的 onCreateView、onStart 和 onResume 方法只被调用;添加时,会调用 Fragment 的 onAttach、onCreate、onCreateView、onStart 和 onResume 方法(按此顺序)。 – Adil Hussain

    【讨论】:

    • 添加到 Rajdeep 的答案中,您会注意到,当 Fragment 分离时,它的 onPauseonStoponDestroyView 方法仅被调用(以该顺序)。另一方面,当Fragment删除 时,它的onPauseonStoponDestroyViewonDestroyonDetach 方法被调用(按此顺序)。类似地,attaching时,只调用FragmentonCreateViewonStartonResume方法;当添加时,会调用FragmentonAttachonCreateonCreateViewonStartonResume方法(按此顺序)。
    • Diane Hackborn here 进行了快速问答。那么为什么我有this 日志呢?你怎么知道 FT.detach() 被调用了?
    • 一个比另一个有什么好处?我想知道一个用例比另一个更有利的用例吗?我总是添加和删除,这很糟糕吗?
    • 最好的简短说明。
    【解决方案2】:

    即使根据 Google 工程师在留言板上的说法,片段管理方法的命名也非常混乱(参见上面的 cmets)。我给自己做了一个小演示,以弄清楚事情是如何运作的。这是我的发现。如果我错了,请随时纠正我。

    要最初将片段添加到 Activity,请使用: getFragmentManager().beginTransaction().add(R.id.container, mFragment).commit().

    这将 Activity 与 Fragment 相关联,并将 View 与 Fragment 相关联。

    以下是生成的生命周期事件和其他重要的方法返回值:

    onAttach()           
    onCreate()           
    onCreateView()       
    onViewCreated()      
    onActivityCreated()  
    onViewStateRestored()
    onStart()            
    onResume()
    
    mFragment.getView() == null: false                    
    mFragment.getActivity() == null: false
    

    要从 Activity 中删除 Fragment,请使用: getFragmentManager().beginTransaction().remove(mFragment).commit()。

    这将删除与视图或活动的任何关联。

    以下是生成的生命周期事件和其他重要的方法返回值:

    onPause()
    onStop()
    onDestroyView()
    onDestroy()
    onDetach()
    
    mFragment.getView() == null: true
    mFragment.getActivity() == null: true
    

    我在这里重新添加了片段

    要从 Activity 中分离添加的 Fragment,请使用: getFragmentManager().beginTransaction().detach(mFragment).commit()。

    这会删除与 View 的任何关联,但会保留与 Activity 的关联。

    以下是生成的生命周期事件和其他重要的方法返回值:

    onPause()                             
    onStop()                              
    onDestroyView()                      
    
    mFragment.getView() == null: true
    mFragment.getActivity() == null: false
    

    要重新附加已分离到 Activity 的 Fragment,请使用: getFragmentManager().beginTransaction().attach(mFragment).commit()。

    这会创建一个新的 View 来与 Fragment 关联并维护 Activity 关联。

    以下是生成的生命周期事件和其他重要的方法返回值:

    onCreateView()                        
    onViewCreated()                       
    onActivityCreated()                   
    onViewStateRestored()                 
    onStart()                             
    onResume()                            
    
    mFragment.getView() == null: false
    mFragment.getActivity() == null: false
    

    其他需要注意的重要事项: 如果您分离一个 Fragment,然后尝试使用 add() 而不是 attach() 再次添加它,似乎没有任何变化。

    如果您尝试通过使用 attach() 而不是 add() 添加已使用 remove() 删除的 Fragment,则似乎没有任何变化。

    当 getView() 返回 null 时,Fragment 可能仍具有对其创建的最后一个 View 的内部引用。此视图不再有效,不应使用。

    【讨论】:

    • 干得好。但是在删除片段后尝试重新附加和重新添加具有相同的效果似乎很有趣。
    • 原来“attach()”不会调用onAttach()。 “detach()”不会调用 onDetach()。
    • 如果您将事务保留在后台堆栈中,其中一些生命周期事件可能会略有变化。