Fragment状态的保存
2016-01-20 15:32
417 查看
当我们需要切换fragment的时候,官方给我们提供了两种方式:replace和add.
首先来看看replace方法:
replace方法相当于先移除remove()原来所有已存在的fragments,然后添加add()当前这个fragment。这就导致了一个问题,我们切换一次,然后再切换回来,相当于重新加载了这个fragment,原来的状态不复存在,这显然与我们的日常使用不符。先做个实现说明一下这个现象。
最下面是两个按钮,用于切换两个Fragment,第一个Fragment中是一个按钮和一个文字,默认显示为你好吗,点击按钮切换文字为我很好,如图所示
但是当我们点击第二个按钮切换到第二个Fragment,然后在切换回来的时候,发现文字又变成默认的了,这就说明重新实例化了fragment对象,Fragment的状态没有得到保存。
我们在每个Fragment的生命周期的onCreateView方法中打印一行Log
每次切换Fragment时我们去看控制台是不是都会打印这句话。
可以看到,每次点击按钮切换Fragment时都会调用Fragment的onCreateView生命周期方法。这就说明使用replace方法切换Fragment是无法保存状态的。
代码如下:
接下来看看add方法:
使用add的时候要和hide和show方法结合起来使用,使用hide隐藏原来的fragment,使用show显示你想要的fragment.
通过实验发现当第一个framgment里面的文字改变之后,在切换回来文字的状态依然是显示为我很好。而且通过控制台我们可以看到两个fragment的onCreateView方法只是在第一次点击按钮的时候会调用,下次切换不在调用。
说明采用add方法很好的保存的fragment的状态,避免每次去实例化新的对象。
代码如下:
但是,在使用add的时候,作为容器的FrameLayout其实有2层,使用replace的话只有一层,多层肯定比一层来的浪费。具体使用什么方法还是看具体的需求吧!
首先来看看replace方法:
replace方法相当于先移除remove()原来所有已存在的fragments,然后添加add()当前这个fragment。这就导致了一个问题,我们切换一次,然后再切换回来,相当于重新加载了这个fragment,原来的状态不复存在,这显然与我们的日常使用不符。先做个实现说明一下这个现象。
最下面是两个按钮,用于切换两个Fragment,第一个Fragment中是一个按钮和一个文字,默认显示为你好吗,点击按钮切换文字为我很好,如图所示
但是当我们点击第二个按钮切换到第二个Fragment,然后在切换回来的时候,发现文字又变成默认的了,这就说明重新实例化了fragment对象,Fragment的状态没有得到保存。
我们在每个Fragment的生命周期的onCreateView方法中打印一行Log
[code]Log.d("Fragment", "FragmentOne------onCreateView");
每次切换Fragment时我们去看控制台是不是都会打印这句话。
可以看到,每次点击按钮切换Fragment时都会调用Fragment的onCreateView生命周期方法。这就说明使用replace方法切换Fragment是无法保存状态的。
代码如下:
[code]public class MainActivity extends FragmentActivity implements OnClickListener { private Button bt1; private Button bt2; private FragmentManager manager; private FragmentTransaction transaction; FragmentOne fragmentOne; FragmentTwo fragmentTwo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt1 = (Button) findViewById(R.id.bt1); bt2 = (Button) findViewById(R.id.bt2); bt1.setOnClickListener(this); bt2.setOnClickListener(this); manager = getSupportFragmentManager(); // 默认选中第一个按钮 bt1.performClick(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt1: if (fragmentOne == null) { fragmentOne = new FragmentOne(); } transaction = manager.beginTransaction(); transaction.replace(R.id.fl_content, fragmentOne); break; case R.id.bt2: if (fragmentTwo == null) { fragmentTwo = new FragmentTwo(); } transaction = manager.beginTransaction(); transaction.replace(R.id.fl_content, fragmentTwo); break; } transaction.commit(); } }
接下来看看add方法:
使用add的时候要和hide和show方法结合起来使用,使用hide隐藏原来的fragment,使用show显示你想要的fragment.
通过实验发现当第一个framgment里面的文字改变之后,在切换回来文字的状态依然是显示为我很好。而且通过控制台我们可以看到两个fragment的onCreateView方法只是在第一次点击按钮的时候会调用,下次切换不在调用。
说明采用add方法很好的保存的fragment的状态,避免每次去实例化新的对象。
代码如下:
[code]public class MainActivity extends FragmentActivity implements OnClickListener{ private Button bt1; private Button bt2; //代表当前的fragment private Fragment content; FragmentOne fragmentOne; FragmentTwo fragmentTwo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt1 = (Button) findViewById(R.id.bt1); bt2 = (Button) findViewById(R.id.bt2); bt1.setOnClickListener(this); bt2.setOnClickListener(this); content = new FragmentOne(); //默认选中第一个Fragment bt1.performClick(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt1: if(fragmentOne == null){ fragmentOne = new FragmentOne(); } switchContent(content, fragmentOne); break; case R.id.bt2: if(fragmentTwo == null){ fragmentTwo = new FragmentTwo(); } switchContent(content, fragmentTwo); break; } } /** * 切换fragment * @param from 要隐藏的fragment * @param to 要显示的fragment */ public void switchContent(Fragment from, Fragment to){ if(content!=to){ content =to; FragmentTransaction transaction= getSupportFragmentManager().beginTransaction(); //此处必须要进行判断,因为同一个fragment只能被add一次,否则会发生异常 if(!to.isAdded()){ //未添加 transaction.hide(from).add(R.id.fl_content, to).commit(); }else{ //添加过直接显示 transaction.hide(from).show(to).commit(); } } } }
但是,在使用add的时候,作为容器的FrameLayout其实有2层,使用replace的话只有一层,多层肯定比一层来的浪费。具体使用什么方法还是看具体的需求吧!
相关文章推荐
- MAC OS中使用ll,la命令
- C语言再学习之进制转换总结
- VS 2012 添加Web引用
- java_listener监听器教程及实例
- 正则表达式限制 账号 密码 邮箱 身份证 手机号的相关代码
- 手机web——自适应网页设计(html/css控制)
- Android得到视频缩略图
- Linux系统文件I/O编程(一)---open()等基本函数
- 讯飞开放平台上线业界首个多生物特征融合认证方案
- PHP curl_setopt函数用法介绍上篇
- LU 分解,采用行连续划分方式下的 MPI 实现
- MFC学习(24)线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法
- 为什么要使用SLF4J而不是Log4J
- android网络编程 四(android-async-http)
- CMOS Image Sensor的测试
- UITextField限制只能输入数字,不能输入其他字符
- A* Pathfinding for Beginners
- 正则表达式:网站源码匹配图片地址
- 采用 MPI_Send 和 MPI_Recv 编写代码来实现 MPI_Allgather 的功能
- Java如果提高反射效率