切换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就可以实现 ...
随机推荐
- Spring Boot 项目发布到 Tomcat 服务器
第 1 步:将这个 Spring Boot 项目的打包方式设置为 war.<packaging>war</packaging> SpringBoot 默认有内嵌的 tomcat ...
- (01)JVM-内存三大核心区域以及分析
package org.burning.sport.jvm; /** * 从JVM调用的角度分析Java程序对内存空间的使用, * 当JVM进程启动的时候,会从类加载器路径中找到包含main方法的入 ...
- 【C#小知识】C#中一些易混淆概念总结(五)---------深入解析C#继承
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...
- SQL Function 自定义函数
目录 产生背景(已经有了存储过程,为什么还要使用自定义函数) 发展历史 构成 使用方法 适用范围 注意事项 疑问 内容 产生背景(已经有了存储过程,为什么还要使用自定义函数) 与存储过程的区别(存 ...
- android学习-Adapter适配器进阶
参考资源 Android 快速开发系列 打造万能的ListView GridView 适配器 实现代码复用,争取打机**的时间. android4.4源码 target=android-19 一般自定 ...
- 4-nginx-反向代理到tomcat及负载均衡
反向代理相比于正向代理, 比如使用搬瓦工时, 就是位于客户端的正想代理, 而反向代理则是服务器端的代理, 主要用于实现请求分发, 负载均衡等功能 正向代理推荐一个: 搬瓦工, 比较好用.. 反向代理主 ...
- typeof null 为什么等于 object?
之前只知道typeof null = object,但是却从来不知道是为什么.最新查阅资料的时候,看到了这个原理,记录下来,方便自己以后查看. 原理是这样的,不同的对象在底层都表示为二进制,在 Jav ...
- 前端项目中使用git来做分支和合并分支,管理生产版本
最近由于公司前端团队扩招,虽然小小的三四团队开发,但是也出现了好多问题.最让人揪心的是代码的管理问题:公司最近把版本控制工具从svn升级为git.前端H5组目前对git的使用还不是很熟悉,出现额多次覆 ...
- Linux内核源码目录
linux和Android的Makefile和android.mk Uboot流程分析(未编辑完) Kernel的IIC驱动分析(未编辑完)
- C#语法之匿名函数和Lambda表达式
上一篇博客主要是对委托和事件做了一小结,这篇是在上一篇博客的基础上对匿名函数和Lambda表达式小结.还是接着上一篇说起,在上一篇中也说了委托是一种数据结构,主要是解决让函数作为参数的问题.在使用委托 ...