Android开发之Fragment详解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android开发之Fragment详解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10474字,纯文字阅读大概需要15分钟。
内容图文
Android 开发之 Fragment 学习
1. 简介:
Fragment 是 Android 3.0 引入的新 API 。 Fragment 代表了 Activity 的子模块,因此可以把 Fragment 理解成 Activity 片段。 Fragment 用于自己的生命周期,也可以接受它自己的输入事件。
Fragment 必须被“嵌入” Activity 中使用,因此虽然 Fragment 也拥有自己的生命周期, 但 Fragment 的生命周期会受它所在的 Activity 的生命周期的控制。例如,当 Activity 暂停时, 该 Activity 内的所有 Fragment 都会暂停;当 Activity 被销毁时,该 Activity 内的所有 Fragment 都会被销毁,只有当该 Activity 处于活动状态时,程序员可通过方法独立地操作 Fragment 。
2.Fragment 的几个特征:
1) Fragment 总是作为 Activity 界面的组成部分, Fragment 可调用 getActivity() 方法获取它所在的 Activity , Activity 调用 FragmentManager 的 findFragmentByld() 或 findFragmentByTag() 方法来获取 Fragment 。
2) 在 Activity 运行过程中,可调用 FragmentManager 的 add() 、 remove() 、 replace() 方法动态地添加、删除或替换 Fragment 。
3) —个 Activity 可以同时组合多个 Fragment; 反过来,一个 Fragment 也可被多 Activity 复用。
4) Fragment 可以响应自己的输入事件,并拥有自己的生命周期,但它们的生命周期直接被其所属的 Activity 的生命周期控制。
Android 3.0 引入 Fragment 的初衷是为了适应大屏幕的平板电脑,由于平板电脑的屏幕比手机屏蒂更大,因此可以容纳更多的 UI 组件,且这些 UI 组件之间存在交互关系。 Fragment 简化了大屏幕 UI 的设计,它不需要开发者管理组件包含关系的复杂变化,开发者使用 Fragment 对 UI 组件进行分组、模块化管理,可以更方便地在运行过程中动态更新 Activity 的用户界面。
例如:有如下新闻浏览界面,该界面需要在屏幕左边显示新闻列表,并在屏幕右边显示新闻内容,此时就可以在
Activity
中显示两个并排的
Fragment
左边的
Fragment
显示新闻列表,
右边的
Fragment
显示新闻内容。由于每个
Fragment
拥有自己的生命周期,并可响应用户输入事件,因此可以非常方便地实现:当用户单击左边列表的指定新闻时,右
Fragment
显示相应的新闻内容。下图左边的“平板电脑”部分显示了这种
Ul
界面
通过使用上面的 Fragment 设计机制,可以取代传统的让一个 Activity 显示新闻列表, 一个 Activity 显示新文内容的设计。
由于 Fragment 是可复用的组件,因此如果需要在正常尺寸的手机屏幕上运行该应用, 可以改为使用两个 Activity , ActivityA 包含 FragmentA 、 ActivityB 包含 FragmentB 。其中 ActivityA 仅包含显示文章列表 FragmentA, 而当用户选择一篇文章时,它会启动包含新闻内容的 ActivityB, 如上图右边的“手机,部分。由此可见, Fragment 可以很好地支持上图所示的两种设计模式。
3. 创建 Fragment
与创建 Activity 类似,开发者实现的 Fragment 必须继承 Fragment 基类, Android 提供了 如下图所示的 Fragment 继承体系。
开发者实现的 Fragment, 可以根据需要继承上图所示的 Fragment 基类或它的任意子类。接下来,实现 Fragment 与实现 Activity 非常相似,它们都需要实现与 Activity 类似的回调方法,例如 onCreate() 、 onCreateView() 、 onStart() 、 onResume() 、 onPause() 、 onStop() 等。
提示:
开发 Fragment 与开发 Activity 非常相似,区别只是开发 Activity 需要继承 Activity 或其子类;但开发 Fragment 需要继承 Fragment 及其子类 . 与此同时,只要将原来写在 Activity 回调方法的代码“移到” Fragment 的回调方法中即可。
通常来说,创建 Fragment 通常需要实现如下三个方法。
1) onCreate(): 系统创建 Fragment 对象后回调该方法,实现代码中只初始化想要在 Fragment 中保持的必要组件,当 fragment 被暂停或者停止后可以恢复。
2) onCreateView(): 当 Fragment 绘制界面组件时会回调该方法。该方法必须返回一个 View, 该 View 也就是该 Fragment 所显示的 View 。
3) onPause(): 当用户离开该 Fragment 时将会回调该方法。
对于大部分 Fragment 而言,通常都会重写上面这三个方法。但是实际上开发者可以根据需要重写 Fragment 的任意回调方法,后面将会详细介绍 Fragment 的生命周期及其回调方法为了控制 Fragment 显示的组件,通常需要重写 onCreateView() 方法,该方法返回的 View 将作为该 Fragment 显示的 View 组件。当 Fragment 绘制界面组件时将会回调该方法。
例如如下方法片段:
// 重写该方法,该方法返回的View将作为Fragment显示的组件 @Override public View onCreateView(LayoutInflater inflater , ViewGroup container, Bundle savedInstanceState) { // 加载/res/layout/目录下的fragment_book_detail.xml布局文件 View rootView = inflater.inflate(R.layout. fragment_book_detail , container, false ); if ( book != null ) { // 让book_title文本框显示book对象的title属性 ((TextView) rootView.findViewById(R.id. book_title )) .setText( book . title ); // 让book_desc文本框显示book对象的desc属性 ((TextView) rootView.findViewById(R.id. book_desc )) .setText( book . desc ); } return rootView; } |
实例:开发发显示图书详情的 Fragment
下面 Fragment 将会显示加载一份简单的界面布局文件,并根据传入的参数来更新界面组件该 Fragment 的代码如下。
3.1创建Fragment:
public class BookDetailFragment extends Fragment { public static final String ITEM_ID = "item_id" ; // 保存该Fragment显示的Book对象 BookContent.Book book ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); // 如果启动该Fragment时包含了ITEM_ID参数 if (getArguments().containsKey( ITEM_ID )) { book = BookContent. ITEM_MAP .get(getArguments() .getInt( ITEM_ID )); //① } }
// 重写该方法,该方法返回的View将作为Fragment显示的组件 @Override public View onCreateView(LayoutInflater inflater , ViewGroup container, Bundle savedInstanceState) { // 加载/res/layout/目录下的fragment_book_detail.xml布局文件 View rootView = inflater.inflate(R.layout. fragment_book_detail , container, false ); if ( book != null ) { // 让book_title文本框显示book对象的title属性 ((TextView) rootView.findViewById(R.id. book_title )) .setText( book . title ); // 让book_desc文本框显示book对象的desc属性 ((TextView) rootView.findViewById(R.id. book_desc )) .setText( book . desc ); } return rootView; } }
|
3.2创建ListFragment:
public class BookDetailFragment extends Fragment { public static final String ITEM_ID = "item_id" ; // 保存该Fragment显示的Book对象 BookContent.Book book ; @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); // 如果启动该Fragment时包含了ITEM_ID参数 if (getArguments().containsKey( ITEM_ID )) { book = BookContent. ITEM_MAP .get(getArguments() .getInt( ITEM_ID )); //① } }
// 重写该方法,该方法返回的View将作为Fragment显示的组件 @Override public View onCreateView(LayoutInflater inflater , ViewGroup container, Bundle savedInstanceState) { // 加载/res/layout/目录下的fragment_book_detail.xml布局文件 View rootView = inflater.inflate(R.layout. fragment_book_detail , container, false ); if ( book != null ) { // 让book_title文本框显示book对象的title属性 ((TextView) rootView.findViewById(R.id. book_title )) .setText( book . title ); // 让book_desc文本框显示book对象的desc属性 ((TextView) rootView.findViewById(R.id. book_desc )) .setText( book . desc ); } return rootView; } }
|
4.Fragmemt 与 Activity 通信
为了在 activity 中显示 Fragment 还必须将 Fragment 添加到 activity 中。
4.1将Fragment添加到activity中有如下两种方式:
1) 在布局文件中添加: 在布局文件中使用 <fragment.../> 元素添加 Fragment ,其中 <fragment.../> 的 android:name 属性必须指定 Fragment 的实现类。
2) 在 Java 代码中添加: 在 Java 代码中通过 FragmentTransaction 对象的 relpace() 或 add() 方法来替换或添加 Fragment 。
提示: Activity 的 getFragmentManager() 方法返回 FragmentManager ,通过调用 FragmentManager 的 beginTransaction() 方法获取 FragmentTransaction 对象。
Activity 的布局文件:
<? xml version = "1.0" encoding = "utf-8" ?> <!-- 定义一个水平排列的 LinearLayout ,并指定使用中等分隔条 --> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:orientation = "horizontal" android:layout_width = "match_parent" android:layout_height = "match_parent" android:layout_marginLeft = "16dp" android:layout_marginRight = "16dp" android:divider = "?android:attr/dividerHorizontal" android:showDividers = "middle" > <!-- 添加一个 Fragment --> < fragment android:name = "com.jph.fragmentdemo.BookListFragment" android:id = "@+id/book_list" android:layout_width = "0dp" android:layout_height = "match_parent" android:layout_weight = "1" /> <!-- 添加一个 FrameLayout 容器 --> < FrameLayout android:id = "@+id/book_detail_container" android:layout_width = "0dp" android:layout_height = "match_parent" android:layout_weight = "3" /> </ LinearLayout > |
Activity 代码:
public class SelectBookActivity extends Activity implements BookListFragment.Callbacks { @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); // 加载/res/layout目录下的main.xml布局文件 setContentView(R.layout. main ); } // 实现Callbacks接口必须实现的方法 @Override public void onItemSelected(Integer id) { // 创建Bundle,准备向Fragment传入参数 Bundle arguments = new Bundle(); arguments.putInt(BookDetailFragment. ITEM_ID , id); // 创建BookDetailFragment对象 BookDetailFragment fragment = new BookDetailFragment(); // 向Fragment传入参数 fragment.setArguments(arguments); // 使用fragment替换book_detail_container容器当前显示的Fragment getFragmentManager().beginTransaction() .replace(R.id. book_detail_container , fragment).commit(); //① } } |
上而的程序中①号粗体字代码就调用了 FragmentTransaction 的 replace() 方法动态更新了 ID 为 book_detail_container 容器(也就是前面布局文件中的 FrameLayout 容器)中显示的 Fragment 。
将 Fragment 添加到 Activity 之后, Fragment 必须与 Activity 交互信息,这就需要 Fragment 能获取它所在的 Activity, Activity 也能获取它所包含的任意的 Fragment 。可按如下方法进行。
4.2在activity中获取Fragement,在Fragment中获取activity的方法:
1) Fragment 获取它所在的 Activity :调用 Fragment 的 getActivity() 方法即可返回它所在的 Activity 。
2) Activity 获取它包含的 Fragment :调用 Activity 关联的 FragmentManager 的 findFragmentByld(int id) 或 findFragmentByTag(String tag) 方法即可获取指定的 Fragment 。
提示:
在界面布局文件中使用 <fragment.../> 元素添加 Fragment 时,可以为 <fragment.../> 元素指定 android:id 或 android:tag 属性,这两个属性都可用于标识该 Fragment ,接下来 Activity 将可通过 findFragmentByld(int id) 或 findFragmentByTag(String tag) 来获取该 Fragment 。
4.3Fragment与Activity可能还需要相互传递数据的方式:
1) Activity 向 Fragment 传递数据 : 在 Activity 中创建 Bundle 数据包 , 并调用 Fragment 的 setArguments(Bundle bundle) 方法即可将 Bundle 数据包传给 Fragment 。
2) Fragment 向 Activity 传递数据或 Activity 需要在 Fragment 运行中进行实时通信: 在 Fragment 中定义一个内部回调接口,再让包含该 Fragment 的 Activity 实现该回调接口,这样 Fragment 即可调用该回调方法将数据传给 Activity 。
3) 通过广播的方式。
5.Fragment 管理与 Fragment 事务
前面介绍了 Activity 与 Fragment 交互相关的内容,其实 Activity 管理 Fragment 主要依靠 FragmentManger 。
5.1FragmentMange的功能:
1) 使用 findFragmentByld() 或 findFragmentByTag() 方法来获取指定 Fragment 。
2) 调用 popBackStack() 方法将 Fragment 从后台找中弹出(模拟用户按下 BACK 按键)。
3) 调用 addOnBackStackChangeListener() 注册个监听器,用于监听后台栈的变化。如果需要添加、删除、替换 Fragment ,则需要借助 FragmentTransaction 对象, FragmentTransaction 代表 Activity 对 Fragment 执行的多个改变。
提示:
FragmentTransaction 也被翻译为 Fragment 事务。与数据库事务类似的是,数据库事务代表了对底层数组的多个更新操作;而 Fragment 事务则代表了 Activity 对 Fragment 执行的多个改变操作。
每个 FragmentTransaction 可以包含多个对 Fragment 的修改,比如包含调用多个 add() 、 replace() 、和 remove() 操作,最后调用 commit() 提交事务即可。
在调用 commit() 之前,开发者也可调用 addToBackStack() 将事务添加到 back 栈,该栈由 Activity 负责管理,这样允许用户按 BACK 按键返回到前一个 Fragment 状态。
// 创建一个新的Fragment并打开事务 Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); // 替换该界面中fragment_container容器内的Fragment transaction.replace(R.id.fragment_container, newFragment); // 将事务添加到back栈,允许用户按back按键返回到替换Fragment之前的状态 transaction.addToBackStack(null); // 提交事务 transaction.commit(); |
在上面的示例代码中, newFragment 替换了当前界面布 局中 ID 为 fragment_container 的容器内的 Fragment, 由于程序调用了 addToBackStack() 将该 replace 操作添加到了 back 栈中,因此用户可以通过按下 BACK 按键返回替换之前的状态。
6.Fragment 的生命周期:
与 Activity 类似的是, Fragment 也存在如下状态。
? 活动状态:当前 Fragment 位于前台,用户可见,可以获得焦点。
? 暂停状态:其他 Activity 位于前台,该 Fragment 依然可见,只是不能获得焦点。
? 停止状态:该 Fragment 不可见,失去焦点。
? 销毁状态:该 Fragment 被完全删除,或该 Fragment 所在的 Activity 被结束。
从上图可以看出,在 Fragment 的生命周期中,如下方法 会被系统回调。
? onAttach () : 当该 Fragment 被添加到 Activity 时被回调。该方法只会被调用一次。
? onCreate (Bundle savedStatus): 创建 Fragment 时被回调。该方法只会被调用一次。
? onCreateView (): 每次创建、绘制该 Fragment 的 View 组件时回调该方法, Fragment 将会显示该方法返回的 View 组件。
? onActivityCreated (): 当 Fragment 所在的 Activity 被启动完成后回调该方法。
? onStart (): 启动 Fragment 时被回调。
? onResume (): 恢复 Fragment 时被回调, onStart() 方法后一定会回调 ()onResume() 方法。
? onPause (): 暂停 Fragment 时被回调。
? onStop (): 停止 Fragment 时被回调。
? onDestroyView (): 销毁该 Fragment 所包含的 View 组件时调用。
? onDestroy (): 销毁 Fragment 时被回调。该方法只会被调用一次。
? onDetach (): 将该 Fragment 从 Activity 中被删除、被替换完成时回调该方法, onDestroy() 方法后一定会回调 onDetach() 方法。该方法只会被调用一次。
原文:http://blog.csdn.net/fengyuzhengfan/article/details/39455057
内容总结
以上是互联网集市为您收集整理的Android开发之Fragment详解全部内容,希望文章能够帮你解决Android开发之Fragment详解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。