Activity与Fragment
Fragment是Android honeycomb 3.0新增的概念,Fragment名为碎片不过却和Activity十分相似。
Fragment是用来描述一些行为或一部分用户界面在一个Activity中,
(1)你可以合并多个fragment在一个单独的activity中建立多个UI面板,
(2)同时重用fragment在多个activity中。
你可以认为fragment作为一个activity中的一节模块 ,fragment有自己的生命周期,接收自己的输入事件,你可以添加或移除从运行中的activity。
从中可以看出:一个fragment必须总是嵌入在一个activity中,同时fragment的生命周期 受 activity而影响。当activity 暂停,那么所有在这个activity的fragments将被destroy释放。
处理Fragment的生命周期
宿主activity的声明周期直接影响到fragment的生命周期。
Activity的生命周期:
Fragment生命周期:
创建一个fragment你必须创建一个Fragment的子类或存在的子类,比如类似下面的代码
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.android_fragment, container, false);
}
}
onAttach()
当fragment和activity被关联时调用。
onCreate()
当fragment创建时被调用,你应该初始化一些实用的组件,比如在fragment暂停或停止时需要恢复的
onCreateView()
当系统调用fragment在首次绘制用户界面时,如果画一个UI在你的fragment你必须返回一个View当然了你可以返回null代表这个fragment没有UI.
onActivityCreated()
当activity的onCreate()方法返回时调用。
onResumed()
在running状态下的可见状态。
onPaused()
另一个activity在前景运行,并且享有焦点,但是这个fragment所在的activity仍然可见(前景activity部分遮挡或者是半透明的)。
onStop()
fragment不可见。可能是因为宿主activity处于stopped状态,或者fragment被remove掉,然后加在了back stack中。
一个处于stopped状态的activity还是存活状态的,所有的状态和成员信息会被系统保持。但是,它不再被用户可见,并且如果宿主activity被kill掉,它也会被kill掉。
onDestroyView()
当fragment的UI被移除的时候调用。
onDetach()
当fragment和activity去关联时调用。
数据存储和恢复
和Activity类似,可以用Bundle类对象保存fragment的状态,当activity的进程被kill之后,需要重建activity时,可以用于恢复fragment的状态。
存储时利用onSaveInstanceState()回调函数,恢复时是在 onCreate()
, onCreateView()
, 或者onActivityCreated()
里。
两者的区别
1.fragment显得更加灵活。可以直接在XML文件中添加<fragment/>,Activity则不能。
eg:
<fragment
Android:id="@+id/left_fragment"
Android:name="com.example.fragmenttest.LeftFragment"
…
…
…/>
2.可以在一个界面上灵活的替换一部分页面,activity不可以,做不到。
替换的时候注意要将这个fragment放在返回栈上。
3.fragment和Activity之间的通信:(也就是控件的相互操控)
fragment控制fragment:得到一个Activity,然后通过这个Activity的getFragmentManager()获得该Fragment的实例。
fragment控制Activity:这个很简单。每个Fragment都有getActivity()得到一个Activity的实例:
View listView = getActivity().findViewById(R.id.list);PS:在当前activity和fragment已经进行关联的情况下否则返回null。
Activity控制fragment:activity也可以获得一个fragment的引用,从而调用fragment中的方法:
xxxFragment xxx=getFragmentManager().findFragmentById();
Activity控制Activity:这个显然是通过Intent活动之间的通信完成。别忘了在被打开的活动中创建Intent和得到Intent一起进行,写个静态的actionStart()。
4.fragment和Activity中控件的加载
Fragment的载入是通过OnCreateView的时候通过inflater.inflate()加载布局,然后通过修改main.xml,在main.xml上增加注册fragment标签,然后通过android:name来载入你已经通过inflater加载的隐藏布局。
有几个关键点:fragment是通过inflater加载View然后在main.xml中注册得到的。当然如果你可以在fragment中得到View那就可以通过View.findViewId()来操控fragment上的具体控件。
5.动态加载不同的fragment:
首先,监听你的按钮。
1.创建待加载fragment的实例
2.得到FragmentManager,在actibity中可以直接调用getFragmentManager()方法获得。
3.调用Manager的BeginTansation()
4.用replace()改变不同的Fragment
5.commit事务。
6.Back Stack
activity和fragment生命周期最重要的不同之处是它们如何存储在各自的back stack中。
Activity停止时,是存在一个由系统维护的back stack中,但是当fragment停止(被remove)时,需要程序员显式地调用addToBackStack()
,并且fragment是存在一个由宿主activity掌管的back stack中。
创建事件回调
些情况下,可能需要fragment和activity共享事件,一个比较好的做法是在fragment里面定义一个回调接口,然后要求宿主activity实现它。
当activity通过这个接口接收到一个回调,它可以同布局中的其他fragment分享这个信息。
例如,一个新闻显示应用在一个activity中有两个fragment,一个fragment A显示文章题目的列表,一个fragment B显示文章。
所以当一个文章被选择的时候,fragment A必须通知activity,然后activity通知fragment B,让它显示这篇文章。
这个情况下,在fragment A中声明一个这样的接口OnArticleSelectedListener:
public static class FragmentA extends ListFragment {
...
// Container Activity must implement this interface
public interface OnArticleSelectedListener {
public void onArticleSelected(Uri articleUri);
}
...
}
之后包含这个fragment的activity实现这个OnArticleSelectedListener接口,用覆写的onArticleSelected()方法将fragment A中发生的事通知fragment B。
为了确保宿主activity实现这个接口,fragment A的onAttach()
方法(这个方法在fragment 被加入到activity中时由系统调用)中通过将传入的activity强制类型转换,实例化一个OnArticleSelectedListener对象:
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
...
}
如果activity没有实现这个接口,fragment将会抛出ClassCastException异常,如果成功了,mListener将会是activity实现OnArticleSelectedListener接口的一个引用,所以通过调用OnArticleSelectedListener接口的方法,fragment A可以和activity共享事件。
比如,如果fragment A是ListFragment的子类,每一次用户点击一个列表项目,系统调用fragment中的onListItemClick()
方法,在这个方法中可以调用onArticleSelected()方法与activity共享事件。
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Append the clicked item's row ID with the content provider Uri
Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
// Send the event and Uri to the host activity
mListener.onArticleSelected(noteUri);
}
...
}
参考资料
API Guides: Fragments
http://developer.android.com/guide/components/fragments.html
http://www.cnblogs.com/mengdd/archive/2013/01/11/2856374.html
Activity与Fragment的更多相关文章
- EventBus实现activity跟fragment交互数据
最近老是听到技术群里面有人提出需求,activity跟fragment交互数据,或者从一个activity跳转到另外一个activity的fragment,所以我给大家介绍一个开源项目,EventBu ...
- activity与fragment之间传递数据
总结:无论是activity给fragment传递数据,还是fragment给activity传递数据,都把activity和fragment都当做一个普通的对象,调用它的方法,传递参数. 1.Fra ...
- Android 数据传递(二)Activity与fragment之间的通信
在网上找到了一篇总结的非常好的文章,我这里就贴出他的博文地址.自己就不再写这个方面的总结了. Activity与Fragment通信(99%)完美解决方案
- Android Activity和Fragment的转场动画
Android Activity和Fragment的转场动画 Activity转场动画 Activity的转场动画是通过overridePendingTransition(int enterAnim, ...
- Android showing LoadingView or EmptyView for Activity or Fragment
这几天利用一些时间,整理了一下,写了一个简单的工具类,用来快速的显示LoadingView或者EmptyView,以前都是定义一个layout,根布局为FrameLayout,再在layout布局文件 ...
- Activity与Fragment的生命周期
今天看到一张图,详细描述了Activity和Fragment的生命周期,好资源共享咯!
- 一句话、一张图记住Activity和Fragment之间错综复杂的生命周期关系
如果我们在Fragment和它的宿主Activity的生命周期中都加上Log日志,你能顺利写出他们的执行顺序吗?我们先来看一张Google官方的图片: 咋一听,Activity生命周期有七个方法,Fr ...
- Activity和Fragment生命周期变化
情形一:启动应用加载Activity和Fragment Activity::onCreate Fragment::onAttach Fragment::onCreate Fragment::onCre ...
- Activity与Fragment之间的通信
由于Fragment的生命周期完全依赖宿主Activity,所以当我们在使用Fragment时难免出现Activity和Fragment间的传值通信操作. 1.Activity向Fragment,通过 ...
随机推荐
- 【Alpha】Daily Scrum Meeting第一次
一.本次Daily Scrum Meeting主要内容 代码任务细分 服务器搭建 每个人时间分配及安排 二.项目进展 学号尾数 今天做的任务 任务完成度 明天要做的任务 612 写代码框架 30% 主 ...
- maven项目打包成可执行的jar
编写功能类: package com.hpay.FileToZkUtil; import java.io.File; import java.io.FileInputStream; import ja ...
- centos 安装 rabbitMQ
此类文章一大堆,本文主要站在开发角度保证基本rabbitmq的基本访问. 系统:centos6 64bit 官方指引:https://www.rabbitmq.com/install-rpm.html ...
- jquery--常用的函数2
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- asp.net中membership使用oracle数据库(二)
需要安装的东西都准备好了,继续生成后台表.过程.函数.触发器等.ps/sql中 @@E:\oracle\product\11.2.0\client_1\ASP.NET\SQL\InstallAllOr ...
- Map java中的map 如何修改Map中的对应元素
Map java中的map 如何修改Map中的对应元素 Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象. Map的接口 Map ...
- Spring Schedule 任务调度实现
我们都知道任务调度可以用Quartz,但对于简单的定时任务,可以直接用Spring内置的Schedule来实现.可以由两种方式,注释+XML配置 注解方式: 注解也要先在sping.xml配置文件中配 ...
- java学习第四天 类和变量
java也属于面向对象的编程 面向对象的三大特征: 封装 继承 多态 类 对象 对象:真实存在的唯一的事物 面向对象编程(oop)思想力图使对计算机语言中的事物的描述和自然界中的事物尽可能保持一致 ...
- vs2010 在64bits系统下编译
vs只有32bits的没有64bits. 本来程序没问题,后面一直报错 LIBCMTD.lib(close.obj) : error LNK2001 LNK2019 换了各种 MD/MT/MTD 都没 ...
- MongoDB游标操作(4)
游标是什么? 通俗的说,游标不是查询结果,而是查询的返回资源,或者接口. 通过这个接口,你可以逐条读取. 声明游标: var cursor = db.collectioName.find(query ...