资讯动态

Android入门教程 | Fragment 基础概念

发布时间:2026/8/27 12:51:52 来源:尧图企业网站定制
什么是FragmentFragment直译为“碎片”“片段”。 Fragment 表示 FragmentActivity 中的行为或界面的一部分。可以在一个 Activity 中组合多个片段从而构建多窗格界面并在多个 Activity 中重复使用某个片段。可以将片段视为 Activity 的模块化组成部分它具有自己的生命周期能接收自己的输入事件并且可以在 Activity 运行时添加或移除片段这有点像可以在不同 Activity 中重复使用的“子 Activity”。片段必须始终托管在 Activity 中其生命周期直接受宿主 Activity 生命周期的影响。例如当 Activity 暂停时Activity 的所有片段也会暂停当 Activity 被销毁时所有片段也会被销毁。不过当 Activity 正在运行处于已恢复生命周期状态时可以独立操纵每个片段如添加或移除片段。当执行此类片段事务时也可将其添加到由 Activity 管理的返回栈 — Activity 中的每个返回栈条目都是一条已发生片段事务的记录。借助返回栈用户可以通过按返回按钮撤消片段事务后退。Fragment的优点Fragment加载灵活替换方便。定制你的UI在不同尺寸的屏幕上创建合适的UI提高用户体验。可复用页面布局可以使用多个Fragment不同的控件和内容可以分布在不同的Fragment上。使用Fragment可以少用一些Activity。一个Activity可以管辖多个Fragment。Fragment生命周期Fragment 类的代码与 Activity 非常相似。它包含与 Activity 类似的回调方法如 onCreate()、onStart()、onPause() 和 onStop()。实际上如果要将现有 Android 应用转换为使用片段可能只需将代码从 Activity 的回调方法移入片段相应的回调方法中。通常至少应实现以下生命周期方法onCreate() 系统会在创建片段时调用此方法。当片段经历暂停或停止状态继而恢复后如果希望保留此片段的基本组件则应在实现中将其初始化。onCreateView() 系统会在片段首次绘制其界面时调用此方法。如要为片段绘制界面从此方法中返回的 View 必须是片段布局的根视图。如果片段未提供界面可以返回 null。onPause() 系统会将此方法作为用户离开片段的第一个信号但并不总是意味着此片段会被销毁进行调用。通常应在此方法内确认在当前用户会话结束后仍然有效的任何更改因为用户可能不会返回。可能还想扩展几个子类而非 Fragment 基类DialogFragment 显示浮动对话框。使用此类创建对话框可有效代替使用 Activity 类中的对话框辅助方法因为您可以将片段对话框纳入由 Activity 管理的片段返回栈从而使用户能够返回清除的片段。ListFragment 显示由适配器如 SimpleCursorAdapter管理的一系列项目类似于 ListActivity。该类提供几种管理列表视图的方法如用于处理点击事件的 onListItemClick() 回调。请注意显示列表的首选方法是使用 RecyclerView而非 ListView。在此情况下需在列表布局中创建包含 RecyclerView 的片段。如需了解具体操作方法请参阅使用 RecyclerView 创建列表PreferenceFragmentCompat 以列表形式显示 Preference 对象的层次结构。此类用于为应用创建设置屏幕。创建Fragment使用自定义界面片段通常用作 Activity 界面的一部分并且会将其自己的布局融入 Activity。如要为片段提供布局必须实现onCreateView()回调方法Android 系统会在片段需要绘制其布局时调用该方法。此方法的实现所返回的 View 必须是片段布局的根视图。如要从 onCreateView() 返回布局可以通过 XML 中定义的布局资源来扩展布局。为帮助您执行此操作onCreateView() 提供了一个 LayoutInflater 对象。例如以下这个 Fragment 子类从example_fragment.xml文件加载布局publicstaticclassExampleFragmentextendsFragment{OverridepublicViewonCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){// Inflate the layout for this fragmentreturninflater.inflate(R.layout.example_fragment,container,false);}}传递至onCreateView()的 container 参数是片段布局将插入到的父级 ViewGroup来自 Activity 的布局。savedInstanceState 参数是在恢复片段时提供上一片段实例相关数据的 Bundle处理片段生命周期部分对恢复状态做了详细阐述。inflate() 方法带有三个参数想要扩展的布局的资源 ID。将作为扩展布局父项的 ViewGroup。传递 container 对系统向扩展布局的根视图由其所属的父视图指定应用布局参数具有重要意义。指示是否应在扩展期间将扩展布局附加至 ViewGroup第二个参数的布尔值。在本例中此值为 false因为系统已将扩展布局插入 container而传递 true 值会在最终布局中创建一个多余的视图组。接下来需将该片段添加到您的 Activity 中。向Activity添加Fragment通常片段会向宿主 Activity 贡献一部分界面作为 Activity 整体视图层次结构的一部分嵌入到 Activity 中。可以通过两种方式向 Activity 布局添加片段以下为代码片段并非完整代码。静态方式在 Activity 的布局文件内声明片段。 在本例中您可以将片段当作视图来为其指定布局属性。例如以下是拥有两个片段的 Activity 的布局文件?xml version1.0encodingutf-8?LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:orientationhorizontalandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentfragment android:namecom.example.news.ArticleListFragmentandroid:idid/listandroid:layout_weight1android:layout_width0dpandroid:layout_heightmatch_parent/fragment android:namecom.example.news.ArticleReaderFragmentandroid:idid/viewerandroid:layout_weight2android:layout_width0dpandroid:layout_heightmatch_parent//LinearLayoutfragment中的android:name属性指定要在布局中进行实例化的 Fragment 类。创建此 Activity 布局时系统会将布局中指定的每个片段实例化并为每个片段调用onCreateView()方法以检索每个片段的布局。系统会直接插入片段返回的 View从而代替fragment元素。注意每个片段都需要唯一标识符重启 Activity 时系统可使用该标识符来恢复片段也可以使用该标识符来捕获片段从而执行某些事务如将其移除。可以通过两种方式为片段提供 ID 为 android:id 属性提供唯一 ID。 为 android:tag 属性提供唯一字符串。Java代码加载Fragment或者通过编程方式将片段添加到某个现有 ViewGroup。 在 Activity 运行期间您可以随时将片段添加到 Activity 布局中。您只需指定要将片段放入哪个 ViewGroup。如要在 Activity 中执行片段事务如添加、移除或替换片段则必须使用 FragmentTransaction 中的 API。如下所示可以从 FragmentActivity 获取一个 FragmentTransaction 实例FragmentManager fragmentManagergetSupportFragmentManager();FragmentTransaction fragmentTransactionfragmentManager.beginTransaction();然后可以使用add()方法添加一个片段指定要添加的片段以及将其插入哪个视图。例如ExampleFragment fragmentnewExampleFragment();fragmentTransaction.add(R.id.fragment_container,fragment);fragmentTransaction.commit();传递到add()的第一个参数是 ViewGroup即应放置片段的位置由资源 ID 指定第二个参数是要添加的片段。 一旦通过 FragmentTransaction 做出了更改就必须调用commit()以使更改生效。管理Fragment如要管理 Activity 中的片段需使用 FragmentManager。如要获取它请从 Activity 调用getSupportFragmentManager()。可使用 FragmentManager 执行的操作包括通过findFragmentById()针对在 Activity 布局中提供界面的片段或 findFragmentByTag()针对提供或不提供界面的片段获取 Activity 中存在的片段。通过popBackStack()模拟用户发出的返回命令使片段从返回栈中弹出。通过addOnBackStackChangedListener()注册侦听返回栈变化的侦听器。也可使用 FragmentManager 打开一个 FragmentTransaction通过它来执行某些事务如添加和移除片段。执行Fragment事务在 Activity 中使用片段的一大优点是可以通过片段执行添加、移除、替换以及其他操作从而响应用户交互。提交给 Activity 的每组更改均称为事务并且可使用 FragmentTransaction 中的 API 来执行一项事务。也可将每个事务保存到由 Activity 管理的返回栈内从而让用户能够回退片段更改类似于回退 Activity。如下所示可以从 FragmentManager 获取一个 FragmentTransaction 实例FragmentManager fragmentManagergetSupportFragmentManager();FragmentTransaction fragmentTransactionfragmentManager.beginTransaction();每个事务都是想要同时执行的一组更改。可以使用 add()、remove() 和 replace() 等方法为给定事务设置您想要执行的所有更改。然后如要将事务应用到 Activity必须调用 commit()。不过在调用 commit() 之前可能希望调用 addToBackStack()以将事务添加到片段事务返回栈。该返回栈由 Activity 管理允许用户通过按返回按钮返回上一片段状态。例如以下示例说明如何将一个片段替换为另一个片段以及如何在返回栈中保留先前的状态// Create new fragment and transactionFragment newFragmentnewExampleFragment();FragmentTransaction transactiongetSupportFragmentManager().beginTransaction();// Replace whatever is in the fragment_container view with this fragment,// and add the transaction to the back stacktransaction.replace(R.id.fragment_container,newFragment);transaction.addToBackStack(null);// Commit the transactiontransaction.commit();在本例中newFragment 会替换目前在 R.id.fragment_container ID 所标识的布局容器中的任何片段如有。通过调用 addToBackStack()可以将替换事务保存到返回栈以便用户能够通过按返回按钮撤消事务并回退到上一片段。然后FragmentActivity 会自动通过 onBackPressed() 从返回栈检索片段。如果向事务添加多个更改如又一个 add() 或 remove()并调用 addToBackStack()则调用 commit() 前应用的所有更改都将作为单一事务添加到返回栈并且返回按钮会将它们一并撤消。向 FragmentTransaction 添加更改的顺序无关紧要不过必须最后调用 commit()。 如果要向同一容器添加多个片段则添加片段的顺序将决定它们在视图层次结构中出现的顺序。 如果没有在执行删除片段的事务时调用 addToBackStack()则事务提交时该片段会被销毁用户将无法回退到该片段。不过如果在删除片段时调用 addToBackStack()则系统会停止该片段并随后在用户回退时将其恢复。调用 commit() 不会立即执行事务而是在 Activity 的界面线程“主”线程可执行该操作时再安排该事务在线程上运行。不过如有必要也可以从界面线程调用 executePendingTransactions()以立即执行 commit() 提交的事务。通常不必这样做除非其他线程中的作业依赖该事务。注意只能在 Activity 保存其状态当用户离开 Activity之前使用 commit() 提交事务。如果试图在该时间点后提交则会引发异常。这是因为如需恢复 Activity则提交后的状态可能会丢失。对于丢失提交无关紧要的情况请使用commitAllowingStateLoss()。生命周期变化Fragment被创建的时候它会经历以下状态onAttach()onCreate()onCreateView()onActivityCreated()Fragment 对用户可见的时候它会经历以下状态onStart()onResume()Fragment进入“后台模式”的时候它会经历以下状态onPause()onStop()Fragment被销毁了或者持有它的activity被销毁了它会经历以下状态onPause()onStop()onDestroyView()onDestroy()onDetach()Fragment与Activity不同的生命周期Fragment 的大部分状态都和 Activity 很相似但 fragment 有一些新的状态。Fragment不同于Activity的生命周期onAttached()—— 当fragment被加入到activity时调用在这个方法中可以获得所在的activity。onCreateView()—— 当activity要得到fragment的layout时调用此方法fragment在其中创建自己的layout(界面)。onActivityCreated()—— 当activity的onCreated()方法返回后调用此方法onDestroyView()—— 当fragment中的视图被移除的时候调用这个方法。onDetach()—— 当fragment和activity分离的时候调用这个方法。一旦activity进入resumed状态也就是running状态你就可以自由地添加和删除fragment了。因此只有当activity在resumed状态时fragment的生命周期才能独立的运转其它时候是依赖于activity的生命周期变化的。处理Fragment生命周期管理片段生命周期与管理 Activity 生命周期很相似。和 Activity 一样片段也以三种状态存在已恢复片段在运行中的 Activity 中可见。已暂停另一个 Activity 位于前台并具有焦点但此片段所在的 Activity 仍然可见前台 Activity 部分透明或未覆盖整个屏幕。已停止片段不可见。宿主 Activity 已停止或片段已从 Activity 中移除但已添加到返回栈。已停止的片段仍处于活动状态系统会保留所有状态和成员信息。不过它对用户不再可见并随 Activity 的终止而终止。 与 Activity 一样您也可使用 onSaveInstanceState(Bundle)、ViewModel 和持久化本地存储的组合在配置变更和进程终止后保留片段的界面状态。如要了解保留界面状态的更多信息请参阅保存界面状态。对于 Activity 生命周期与片段生命周期而言二者最显著的差异是在其各自返回栈中的存储方式。默认情况下Activity 停止时会被放入由系统管理的 Activity 返回栈中。不过只有在移除片段的事务执行期间通过调用 addToBackStack() 显式请求保存实例时系统才会将片段放入由宿主 Activity 管理的返回栈。在其他方面管理片段生命周期与管理 Activity 生命周期非常相似对此可采取相同的做法。注意如果 Fragment 中需要 Context 对象则可以调用 getContext()。但请注意只有在该片段附加到 Activity 时才需调用 getContext()。如果尚未附加该片段或者其在生命周期结束期间已分离则 getContext() 返回 null。Fragment相关面试题1. 如何切换 fragement不重新实例化翻看了 Android 官方 Doc和一些组件的源代码发现 replace()这个方法只是在上一个 Fragment不再需要时采用的简便方法.正确的切换方式是 add()切换时 hide()add()另一个 Fragment再次切换时只需 hide()当前show()另一个。这样就能做到多个 Fragment 切换不重新实例化2. Fragment 的的优点Fragment 可以使你能够将 activity 分离成多个可重用的组件每个都有它自己的生命周期和UI。Fragment 可以轻松得创建动态灵活的 UI 设计可以适应于不同的屏幕尺寸。从手机到平板电脑。Fragment 是一个独立的模块,紧紧地与 activity 绑定在一起。可以运行中动态地移除、加入、交换等。Fragment 提供一个新的方式让你在不同的安卓设备上统一你的 UI。Fragment 解决 Activity 间的切换不流畅轻量切换。Fragment 替代 TabActivity 做导航性能更好。Fragment 在 4.2.版本中新增嵌套 fragment 使用方法能够生成更好的界面效果。3. Fragment 如何实现类似 Activity 栈的压栈和出栈效果Fragment 的事物管理器内部维持了一个双向链表结构该结构可以记录我们每次 add 的Fragment 和 replace 的 Fragment然后当我们点击 back 按钮的时候会自动帮我们实现退栈操作。4. Fragment 的 replace 和 add 方法的区别Fragment 本身并没有 replace 和 add 方法这里的理解应该为使用 FragmentManager 的 replace和 add 两种方法切换 Fragment 时有什么不同。我们经常使用的一个架构就是通过 RadioGroup 切换 Fragment每个 Fragment 就是一个功能模块。Fragment 的容器一个 FrameLayoutadd 的时候是把所有的 Fragment 一层一层的叠加到了FrameLayout 上了而 replace 的话首先将该容器中的其他 Fragment 去除掉然后将当前 Fragment添加到容器中。一个 Fragment 容器中只能添加一个 Fragment 种类如果多次添加则会报异常导致程序终止而 replace 则无所谓随便切换。因为通过 add 的方法添加的 Fragment每个 Fragment 只能添加一次因此如果要想达到切换效果需要通过 Fragment 的的 hide 和 show 方法结合者使用。将要显示的 show 出来将其他 hide起来。这个过程 Fragment 的生命周期没有变化。通过 replace 切换 Fragment每次都会执行上一个 Fragment 的 onDestroyView新 Fragment的 onCreateView、onStart、onResume 方法。基于以上不同的特点我们在使用的使用一定要结合着生命周期操作我们的视图和数据。5. Fragment与Activity之间是如何传值的Activity向Fragment传值将要传的值放到bundle对象里 在Activity中创建该Fragment的对象fragment 通过调用 fragment.setArguments()传递到fragment中 在该Fragment中通过调用getArguments()得到bundle对象就能得到里面的值。Fragment向Activity传值在Activity中调用getFragmentManager()得到fragmentManager,调用findFragmentByTag(tag)或者通过findFragmentById(id) FragmentManager fragmentManager getFragmentManager() Fragment fragment fragmentManager.findFragmentByTag(tag)通过回调的方式定义一个接口可以在 Fragment 类中定义接口中有一个空的方法在 fragment 中需要的时候调用接口的方法值可以作为参数放在这个方法中然后让 Activity 实现这个接口必然会重写这个方法这样值就传到了 Activity 中。6. Fragment生命周期onAttach(Contextcontext)在 Fragment 和 Activity 关联上的时候调用且仅调用一次。在该回调中我们可以将 context 转化为 Activity 保存下来从而避免后期频繁调用getAtivity() 获取 Activity 的局面避免了在某些情况下 getAtivity() 为空的异常Activity和 Fragment 分离的情况下。同时也可以在该回调中将传入的Arguments提取并解析在这里强烈推荐通过setArguments给Fragment传参数因为在应用被系统回收时Fragment不会保存相关属性。onCreate在最初创建Fragment的时候会调用和Activity的onCreate类似。View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)在准备绘制Fragment界面时调用返回值为Fragment要绘制布局的根视图当然也可以返回null。注意使用inflater构建View时一定要将attachToRoot指明false因为Fragment会自动将视图添加到container中attachToRoot为true会重复添加报错。onCreateView并不是一定会被调用当添加的是没有界面的Fragment就不会调用比如调用FragmentTransaction的add(Fragment fragment, String tag)方法。onActivityCreated在 Activity 的 onCreated 执行完时会调用。onStart()Fragment对用户可见的时候调用前提是 Activity 已经 started。onResume()Fragment和用户之前可交互时会调用前提是Activity已经resumed。onPause()Fragment和用户之前不可交互时会调用。onStop()Fragment不可见时会调用。onDestroyView()在移除Fragment相关视图层级时调用。onDestroy()最终清楚Fragment状态时会调用。onDetach()Fragment和Activity解除关联时调用。7. ViewPager对Fragment生命周期的影响ViewPagerFragment 是比较常见的组合了一般搭配ViewPager的FragmentPagerAdapter 或 FragmentStatePagerAdapter 使用。不过 ViewPager 为了防止滑动出现卡顿有一个缓存机制默认情况下 ViewPager 会创建并缓存当前页面左右两边的页面如Fragment。此时左右两个 Fragment 都会执行从 onAttach-….-onResume 的生命周期明明 Fragment 没有显示却已经到onResume 了在某些情况下会出现问题。比如数据的加载时机、判断 Fragment 是否可见等。最后分享一份【腾讯技术团队出品】Android零基础入门到精通Android Studio安装教程全套安卓基础教程Android编程入门教程Java语言基础从入门到熟悉Kotlin语言基础从入门到熟悉Android 技术栈从入门到熟悉Android Jetpack 全家桶全面学习对于新手来说可能安装Android Studio存在一定困难你可以看着以下视频一步步的跟着学习安装运行Android Studio 安装教程有了Java阶段的学习这一阶段建议以视频学习为主辅以图书查漏补缺。如果以图书为主可以根据图书讲解敲代码辅以教学视频查漏补缺。遇到问题可以去百度入门的问题一般会有很多人遇到并且给出比较好的解答。需要掌握基本知识点比如四大组件如何使用、如何创建Service、如何进行布局、简单的自定义View、动画、网络通信等常见技术。全套零基础教程已经为你们准备好了需要的可以添加下方二维码免费领取全套安卓基础教程

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价