切换Fragment时实现数据保持
摘要 Fragment设计初衷是为了简化不同屏幕分辨率的开发难度,他将代表一个功能的UI及其相关数据看做一个模块,以便达到复用。可以将Fragment看作是一个可以嵌入布局中的activity,有自己的生命周期。
Fragment设计初衷是为了简化不同屏幕分辨率的开发难度,他将代表一个功能的UI及其相关数据看做一个模块,以便达到复用。可以将Fragment看作是一个可以嵌入布局中的activity,有自己的生命周期。比如我现在在手机上有activityA和activityB,但是在平板上有更大的空间,可以将activityA和activityB的功能展示在同一个界面中,如果没有Fragment我们就无法在不改变代码的情况下将activityA和activityB的功能放在一起。
Fragment的详细介绍请看:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/0828/383.html
在这篇文章中我们先回忆一下他的用法:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
R.id.fragment_container
是fragment
要嵌入的布局控件id。当我想在另外的地方也嵌套一个ExampleFragment
时,可以做同样的操作就能将UI拷贝一份,如果我们是想在R.id.fragment_container
这个控件里面显示另外一个Fragment我们还可以用fragmentTransaction.replace(R.id.fragment_container, fragment2)来替换之前的fragment。
由于可以在同一个地方动态的显示不同的UI,因此Fragment很适合拿来做如下的界面效果:
上面的界面是百度云app的效果,每点击一个tab就切换成一个界面,我们可以很容易想到实现的原理就是点击一个tab 调fragmentTransaction.replace来替换成新的Fragment。
但是频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿或者需要从网络加载数据这样就非常不好了。replace方法是导致切换时重新创建Fragment的元凶,显然我们希望的是使用Fragment, 但是被替代的Fragment不要释放,以便下次切换回来直接就显示。
我们知道ViewPager其实有个FragmentPagerAdapter, FragmentPagerAdapter不光可以用在ViewPager中,还可以用来作为Fragment的切换提供器,其实ViewPager中他的作用也是如此。FragmentPagerAdapter可以将很多个Fragment保存起来以供取出,并且封装了取出的接口,其实还是通过FragmentTransaction来实现的。
我可以这样来实现百度云的效果,如何从FragmentPagerAdapter中取出fragment参考了ViewPager的源码:
package com.nmbb.sample.fragmentswitch;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.FrameLayout;
import android.widget.RadioButton;
public class MainActivity extends FragmentActivity implements
OnCheckedChangeListener, OnClickListener {
private RadioButton mTab1;
private RadioButton mTab2;
private RadioButton mTab3;
private RadioButton mTab4;
private RadioButton mTab5;
private FrameLayout mContainer;
public CompoundButton currentButtonView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTab1 = (RadioButton) findViewById(R.id.radio_button0);
mTab2 = (RadioButton) findViewById(R.id.radio_button1);
mTab3 = (RadioButton) findViewById(R.id.radio_button2);
mTab4 = (RadioButton) findViewById(R.id.radio_button3);
mTab5 = (RadioButton) findViewById(R.id.radio_button4);
mContainer = (FrameLayout) findViewById(R.id.container);
mTab1.setOnCheckedChangeListener(this);
mTab2.setOnCheckedChangeListener(this);
mTab3.setOnCheckedChangeListener(this);
mTab4.setOnCheckedChangeListener(this);
mTab5.setOnCheckedChangeListener(this);
mTab1.setOnClickListener(this);
mTab2.setOnClickListener(this);
mTab3.setOnClickListener(this);
mTab4.setOnClickListener(this);
mTab5.setOnClickListener(this);
mTab1.performClick();
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Fragment fragment = (Fragment) mFragmentPagerAdapter
.instantiateItem(mContainer, buttonView.getId());
mFragmentPagerAdapter.setPrimaryItem(mContainer, , fragment);
mFragmentPagerAdapter.finishUpdate(mContainer);
}
}
private FragmentPagerAdapter mFragmentPagerAdapter = new FragmentPagerAdapter(
getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
switch (position) {
case R.id.radio_button1:
return FragmentTest.instantiation();
case R.id.radio_button2:
return FragmentTest.instantiation();
case R.id.radio_button3:
return FragmentTest.instantiation();
case R.id.radio_button4:
return FragmentTest.instantiation();
case R.id.radio_button0:
default:
return FragmentTest.instantiation();
}
}
@Override
public int getCount() {
return ;
}
};
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
instantiateItem从FragmentManager中查找Fragment,找不到就getItem新建一个,setPrimaryItem设置隐藏和显示,最后finishUpdate提交事务。
mContainer就是xml中的FrameLayout。
FragmentTest
的代码如下:
package com.nmbb.sample.fragmentswitch;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FragmentTest extends Fragment {
public static FragmentTest instantiation(int position) {
FragmentTest fragment = new FragmentTest();
Bundle args = new Bundle();
args.putInt("position", position);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_test, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView text1 = (TextView) view.findViewById(android.R.id.text1);
text1.setText("Fragment " + getArguments().getInt("position", ));
} @Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if (this.getView() != null)
this.getView().setVisibility(menuVisible ? View.VISIBLE : View.GONE);
}
}
其中,下面的代码很关键,没有下面的代码会出现切换tab的时候重影现象:
@Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if (this.getView() != null)
this.getView().setVisibility(menuVisible ? View.VISIBLE : View.GONE);
}
切换Fragment时实现数据保持的更多相关文章
- 让多个Fragment 切换时不重新实例化、FragmentTabHost切换Fragment时避免UI重新加载
http://www.tuicool.com/articles/FJ7VBb FragmentTabHost切换Fragment时避免UI重新加载 不过,初次实现时发现有个缺陷,每次FragmentT ...
- (转载)解决切换Fragment时布局重新实例化
解决切换Fragment时布局重新实例化 作者 instanceof 关注 2015.12.30 17:25* 字数 628 阅读 7616评论 17喜欢 23 关于Fragment 在这简单说一下F ...
- 使用ViewPager切换Fragment时,防止频繁调用OnCreatView
使用ViewPager切换Fragment,我原先使用系统自带的适配器FragmentPagerAdapter. 切换fragment时,频繁调用oncreatview(). 查看FragmentPa ...
- Web端的Tab控件在切换Tab时Load数据出错的处理
我们在应用Web端的Tab控件时,不管是Jquery easyui的还是Ext的Tab控件都会遇到一个问题,在Tab1正在加载数据的时候我们切换到Tab2,再切换回来,Load数据的控件就会出错,出错 ...
- FragmentTabHost切换Fragment时保存状态,避免切换Fragment走onCreateView和onDestroyView方法;
FragmentTabHost这个控件每次切换Fragment,都会走Fragment的onCreateView和onDestroyView方法,多以每次切换都会创建和销毁Fragment实例,先来看 ...
- FragmentTabHost切换Fragment时避免重复加载UI
使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态. 解决办法:在Frag ...
- Android_ FragmentTabHost切换Fragment时避免重复加载UI
使用FragmentTabHost时,Fragment之间切换时每次都会调用onCreateView方法,导致每次Fragment的布局都重绘,无法保持Fragment原有状态. 解决办法:在Frag ...
- Android控件使用FragmentTabHost,切换Fragment;
大部分APP的主界面都很类似,要么底部导航的,要么就是侧滑菜单,还有底部导航+侧滑菜单的:底部导航实现大概有几种方式: TabHost+Fragment RadioGroup+Fragment Fra ...
- Activity内切换fragment实现底部菜单切换遇到的坑
1.一般说来,app底部导航都会设计为5个菜单,可以使用textView,也可使用radioButton,这里我选择用radioButton,给radioButton直接设置selector就可以实现 ...
随机推荐
- zabbix 自定义 key (转)
转自:http://www.cnblogs.com/miclesvic/p/6164303.html 1.在zabbix_agent端zabbix_agentd.conf配置文件中增加自定义Key(/ ...
- excel将内容粘贴到筛选后的可见单元格
默认情况下,筛选后excel表格进行复制粘贴,会贴到隐藏的表格. 可以添加两个辅助列来完成操作:1.在筛选前在表格右边添加"辅助1"列,在第二行输入1,按Ctrl+鼠标左键往下拉到 ...
- maven tomcat插件上传项目到tomcat服务器报错SEVERE: One or more listeners failed to start.
以前觉了maven依赖设置很简单,就是将手动导入jar包转化为自动下载导入 但发现的一个问题, 在使用maven插件tomcat打包上传工具时 tomcat-maven-plugin <buil ...
- java学习-GET方式抓取网页(UrlConnection和HttpClient)
抓取网页其实就是模拟客户端(PC端,手机端...)发送请求,获得响应数据documentation,解析对应数据的过程.---自己理解,错误请告知 一般常用请求方式有GET,POST,HEAD三种 G ...
- j2ee高级开发技术课程第二周(web请求的整个过程、XML)
博客非原创,只是收集整理了一下网上的一些文章 一.web请求的整个过程 1)把URL分割成几个部分:协议.网络地址.资源路径.其中网络地址指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括 ...
- Linux-(touch,cat,nl,more|less,head|tail)
touch命令 1.命令格式: touch [选项]... 文件... 2.命令参数: -a 或--time=atime或--time=access或--time=use 只更改存取时间. -c ...
- paxos协议更新日志
基于Paxos协议的数据同步与传统主备方式最大的区别在与Paxos只需任意超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失. Basic paxos协议更新日志 我们将数据持久 ...
- WPF 进程间传递参数
WPF 进程间传递参数 在软件开发中有时需要在一个软件中启动另一个软件,这时用Process.Start(“软件路径”)可以启动另一个软件.如果在这个过程中还需要传递一些参数给新启动 ...
- NewBluePill源码学习 <一>
NewBluePill的源码也看的差不多了,一直说等有时间了再写学习的一些心得,拖来拖去弄到现在了,时间不是等来的,慢慢开始吧. 0x00 初识硬件虚拟化 硬件虚拟化对大数人来讲还是比较陌生. ...
- ibatis Dynamic总结(ibatis使用安全的拼接语句,动态查询)
ibatis中使用安全的拼接语句,动态查询,ibatis比JDBC的优势之一,安全高效 说明文字在注释中 一.引入 一个小例子 <select id="selectAllProduc ...