Android开发——Fragment知识整理(二)
0. 前言
Android开发中的Fragment的应用非常广泛,在Android开发——Fragment知识整理(一)中简单介绍了关于Fragment的生命周期,常用API,回退栈的应用等知识。这篇将着重于介绍Fragment和Activity之间的通信以及使用Fragment保存Activity数据销毁时数据的一些知识。
1. Fragment与Activity的通信
Fragment是依附于Activity存在的,因此两者之间的通信在所难免。比如Fragment不能响应Intent打开,但是Activity可以,Activity通过Intent中的参数即可决定显示哪个Fragment。Activity应该承担一个Fragment管理者的作用。
我们可以使用getFragmentManager.findFragmentByTag()或者findFragmentById()在Activity中获得Fragment实例,如果在Fragment中需要Context,可以通过getActivity得到当前绑定的Activity的实例。如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()。
在Android开发——Fragment知识整理(一)中我们介绍了点击Fragment1中的按钮实现到Fragment2的跳转,考虑Fragment的重复使用,所以必须降低Fragment与Activity的耦合,不应该在Fragment中直接操作别的Fragment。因此点击按钮的逻辑考虑在Activity中调用。Fragment1重构如下:
public class FragmentOne extends Fragment implements OnClickListener {
private Button mBtn;
public interface OnFragmentClickListener {
void onBtnClick();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
mBtn = (Button) view.findViewById(R.id.id_fragment_one_btn);
mBtn.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
if (getActivity() instanceof OnFragmentClickListener ) {
((OnFragmentClickListener ) getActivity()).onBtnClick();
}
}
}
这样任何Activity均可实现OnFragmentClickListener 来处理Fragment1中的按钮逻辑,实现了Fragment与Activity之间的解耦。以下即为Activity中的按钮逻辑,实现Fragment1到Fragment2的跳转。onCreate中添加Fragment1的逻辑不变。
private FragmentTwo two;
@Override
public void onBtnClick() {
if (two == null) {
two = new FragmentTwo();
}
FragmentTransaction ft= getFragmentManager().beginTransaction();
ft.replace(R.id.id_content, two, "TWO");
ft.addToBackStack(null);
ft.commit();
}
2. Activity的异常销毁
在Android开发——Activity生命周期中我们知道,诸如屏幕旋转等操作会导致Activity的销毁重建,当然Fragment也不能幸免于难。解决方式就是使用savedInstanceState。在Activity的onCreate方法中,Fragment的实例创建需要进行特殊处理,如下所示:
if(savedInstanceState == null) {
one = new FragmentOne();
FragmentTransaction ft= getFragmentManager().beginTransaction();
ft.add(R.id.id_content, one, "ONE");
ft.commit();
}
这样即可实现无论Activity如何被销毁重建,都可以保证Fragment的实例不会被重复创建,数据的恢复和Activity数据恢复的机制类似,Fragment也有onSaveInstanceState()用于保存数据,然后在onCreate()或onCreateView()或onActivityCreated()中进行数据恢复即可。
3. 使用Fragment保存Activity销毁之前的数据
如果Activity在旋转屏幕时异常销毁重建时需要恢复大量的数据,比如包含bitmap,这时在onSaveIntanceState()中使用Bundle来完全恢复你Activity的状态可能是不现实的,因为Bundle中的数据需要能够被序列化和反序列化,并且Bundle不适宜携带大量数据,因此onSaveIntanceState的使用可能会因为开销过大而造成较差的用户体验。这时便可以通过维护一个Fragment(内部维护你想保持的对象引用)来优化Activity重启时的负担。
这时可能有同学会问,Activity都重建了,Fragment不会被重建吗?那是因为Activity中被标识保持的Fragments不会被销毁,因此可以使用Fragment来保存大量的数据。
3.1 继承Fragment并在其中声明引用
public class KeepDataFragment extends Fragment {
//保存一个Bitmap模拟大量数据
private Bitmap data;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public void setData(MyAsyncTask data) {
this.data = data;
}
public Bitmap getData() {
return data;
}
}
这里我们创建KeepDataFragment并继承Fragment,并在其中声明需要保存的数据对象,这里是保存了一个Bitmap,然后提供getter和setter。最后一定要在onCreate调用setRetainInstance(true)。
3.2 MainActivity中的实现
public class MainActivity extends Activity {
private KeepDataFragmentdataFragment;
private ImageViewmImageView;
private BitmapmBitmap;
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.id_imageView);
FragmentManager fm= getFragmentManager();
dataFragment =(RetainedFragment) fm.findFragmentByTag("data");
if (dataFragment == null) {
dataFragment =new RetainedFragment();
fm.beginTransaction().add(dataFragment, "data").commit();
}
mBitmap = dataFragment.getData();
if (mBitmap ==null) {
//下载任务并设置给ImageView
} else{
mImageView.setImageBitmap(mBitmap);
}
}
@Override
public voidonDestroy() {
super.onDestroy();
dataFragment.setData(mBitmap);
}
}
在MainActivity的onCreate()中使用Fragment中的bitmap引用,如果为空则下载并显示,如果不为空,说明是Activity在销毁时在onDestroy()中保存了数据。
但是如果为了更好的用户体验,加入了对话框来达到ProcessDialog的效果,则会在异步任务进行时旋转屏幕出现较多问题,详情可以参考Android开发——异步任务中Activity销毁时的问题。
Android开发——Fragment知识整理(二)的更多相关文章
- Android开发——Fragment知识整理(一)
0. 前言 Fragment,顾名思义是片段的意思,可以把Fragment当成Activity的一个组成部分,甚至Activity的界面可以完全有不同的Fragment组成.Fragment需要被嵌 ...
- 阿里内部资料:Android开发核心知识笔记共2100页,58万字,完整版开放下载
作为一个3-5年的Android工程师,我们经常会遇到这些瓶颈: 1.技术视野窄长期在小型软件公司,外包公司工作,技术视野被限制的太厉害 2.薪资提升难初中级Android岗位薪资上升空间有限,基本上 ...
- Android开发——Fragment的简单使用总结
前言: 之前搞项目的时候,就使用了这个Fragment,中间遇到了许多坑,把坑都解决了,现在写一篇较为简单的Fragment使用总结 Fragment的简单介绍: 简单来说,Fragment其实可以理 ...
- 【Android开发VR实战】二.播放360°全景视频
转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53924006 本文出自[DylanAndroid的博客] [Android开发 ...
- 移动端 Web 开发前端知识整理
文章来源: http://www.restran.net/2015/05/14/mobile-web-front-end-collections/ 最近整理的移动端 Web 开发前端知识,不定期更新. ...
- 【Bugly 技术干货】Android开发必备知识:为什么说Kotlin值得一试
1.Hello, Kotlin Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 1. ...
- Android开发-浅谈架构(二)
写在前面的话 我记得有一期罗胖的<罗辑思维>中他提到 我们在这个碎片化 充满焦虑的时代该怎么学习--用30%的时间 了解70%该领域的知识然后迅速转移芳草鲜美的地方 像游牧民族那样.原话应 ...
- Android开发 - 掌握ConstraintLayout(二)介绍
介绍 发布时间 ConstraintLayout是在2016的Google I/O大会上发布的,经过这么长时间的更新,现在已经非常稳定. 支持Android 2.3(API 9)+ 目前的Androi ...
- Android开发学习笔记(二)——编译和运行原理(1)
http://www.cnblogs.com/Pickuper/archive/2011/06/14/2078969.html 接着上一篇的内容,继续从全局了解Android.在清楚了Android的 ...
随机推荐
- CSS控制Span强制换行亲测
span { word-wrap: break-word; word-break: break-all; white-space: pre-wrap !important; }
- qtcreator minggw 支持c++11
pro文件添加 QMAKE_CXXFLAGS += -std=c++11
- LeetCode题解之Linked List Cycle
1.题目描述 2.问题分析 使用快慢指针方法,一个快指针,一个慢指针,如果到某个时候,快指针追上了慢指针,则说明有环存在. 3.代码 bool hasCycle(ListNode *head) { i ...
- Android应用耗电量统计,无需USB连接
Android应用耗电量统计一直是一个很头疼的问题,手工统计耗时太长,自动化统计又不是非常精准(执行自动化代码需要通过USB连接,而USB又会充电,这就造成统计数据不准).后来从前辈那里得知可以通过a ...
- Sql server 账号被锁住:"the account is currently locked out. The system administrator can unlock it."的解决办法(转载)
今天遇到的问题比较有意思.首先是很久没有打开测试数据库了,今天打开,使用service程序测试的时候出现下面的错误提示:Message: System.Data.SqlClient.SqlExcept ...
- Safari中的Date
在js中处理Date时,发现Safari和其他浏览器的支持方式不一致 1.例如:2017-01-01 12:00:00 在其他浏览器中,使用这个格式的字符串进行new Date操作没有问题,但是在Sa ...
- 不使用 vue-cli 与 vue 模版,使用 Vue2.x + webpack4.x 从零开始一步步搭建项目框架
说明 这是我根据慕课网上的一个课程 Vue+Webpack打造todo应用 过程一步步搭下来的框架,去掉了业务相关的逻辑. 项目最终的效果包括了引入vue框架:使用CSS预处理器:使用babel:引用 ...
- Java AWT
AWT是抽象窗口工具包,是API为Java 程序提供的建立图形用户界面GUI (Graphics User Interface)工具集,AWT可用于Java的applet和applications中. ...
- SDN 第三次上机作业
SDN 第三次上机作业 1.创建拓扑 2.利用OVS命令下发流表,实现vlan功能 3.利用OVS命令查看流表 s1: s2: 4.验证性测试 5.Wireshark 抓包验证
- jquery1.9 下检测浏览器类型和版本的方法
Jquery1.9版本中$.browser已被剔除: 判断浏览器类型: 复制代码 代码如下: $.browser.mozilla = /firefox/.test(navigator.userAgen ...