FragmentPagerAdapter刷新fragment最完美解决方案
FragmentPagerAdapter刷新fragment最完美解决方案
先感谢kingjxl2006的博客文章《Android FragmentPagerAdapter数据刷新notifyDataSetChanged没效果研究》http://blog.sina.com.cn/s/blog_783ede03010173b4.html,没有他的抛砖引玉,就没有这篇博文。
kingjxl2006的办法是清除FragmentManager里面全部缓存的fragment。这很暴力我不赞同,全部清除会造成fragment重新加载,造成不必要的性能损失。
@Override
public Object instantiateItem(ViewGroup container,int position) {
//得到缓存的fragment
Fragment fragment = (Fragment)super.instantiateItem(container,
position);
//得到tag ❶
String fragmentTag = fragment.getTag();
if (fragmentsUpdateFlag[position %fragmentsUpdateFlag.length]) {
//如果这个fragment需要更新
FragmentTransaction ft =fm.beginTransaction();
//移除旧的fragment
ft.remove(fragment);
//换成新的fragment
fragment =fragments[position %fragments.length];
//添加新fragment时必须用前面获得的tag ❶
ft.add(container.getId(), fragment, fragmentTag);
ft.attach(fragment);
ft.commit();
//复位更新标志
fragmentsUpdateFlag[position %fragmentsUpdateFlag.length] =false;
}
return fragment;
}
代码注释得很清楚了,主要思路就是用新的fragment替换FragmentManager里缓存的旧的fragment,重点解释❶的地方,看kingjxl2006文章里的两条代码:
FragmentManager fm;
super(fm);
this.fm = fm;
}
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
public class MainActivity extends FragmentActivity implements
FragmentEvent.OnEventListener {
ViewPager viewPager;
FragmentPagerAdapter adapter;
MainTab01 tab01 = new MainTab01();
MainTab02 tab02 = new MainTab02();
MainTab03 tab03 = new MainTab03();
MainTab04 tab04 = new MainTab04();
MainTab05 tab05 = new MainTab05();
Fragment[] fragments = { tab01, tab02, tab03, tab04 };
boolean[] fragmentsUpdateFlag = { false, false, false, false };
/**
* 底部四个按钮
*/
private LinearLayout tabBtnWeixin;
private LinearLayout tabBtnFrd;
private LinearLayout tabBtnAddress;
private LinearLayout tabBtnSettings;
Handler mainHandler = new Handler() {
/*
* (非 Javadoc)
*
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg) {
// TODO 自动生成的方法存根
super.handleMessage(msg);
switch (msg.what) {
case MSG.INTO_05:
fragments[3] = tab05;
fragmentsUpdateFlag[3] = true;
adapter.notifyDataSetChanged();
break;
default:
}
}
};
class MyFragmentPagerAdapter extends FragmentPagerAdapter {
FragmentManager fm;
MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
this.fm = fm;
}
@Override
public int getCount() {
return fragments.length;
}
@Override
public Fragment getItem(int position) {
Fragment fragment = fragments[position % fragments.length];
Log.i(Common.TAG, "getItem:position=" + position + ",fragment:"
+ fragment.getClass().getName() + ",fragment.tag="
+ fragment.getTag());
return fragments[position % fragments.length];
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//得到缓存的fragment
Fragment fragment = (Fragment) super.instantiateItem(container,
position);
//得到tag,这点很重要
String fragmentTag = fragment.getTag();
if (fragmentsUpdateFlag[position % fragmentsUpdateFlag.length]) {
//如果这个fragment需要更新
FragmentTransaction ft = fm.beginTransaction();
//移除旧的fragment
ft.remove(fragment);
//换成新的fragment
fragment = fragments[position % fragments.length];
//添加新fragment时必须用前面获得的tag,这点很重要
ft.add(container.getId(), fragment, fragmentTag);
ft.attach(fragment);
ft.commit();
//复位更新标志
fragmentsUpdateFlag[position % fragmentsUpdateFlag.length] = false;
}
return fragment;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.id_viewpager);
tabBtnWeixin = (LinearLayout) findViewById(R.id.id_tab_bottom_weixin);
tabBtnFrd = (LinearLayout) findViewById(R.id.id_tab_bottom_friend);
tabBtnAddress = (LinearLayout) findViewById(R.id.id_tab_bottom_contact);
tabBtnSettings = (LinearLayout) findViewById(R.id.id_tab_bottom_setting);
adapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
private int currentIndex;
@Override
public void onPageSelected(int position) {
resetTabBtn();
switch (position) {
case 0:
((ImageButton) tabBtnWeixin
.findViewById(R.id.btn_tab_bottom_weixin))
.setImageResource(R.drawable.tab_weixin_pressed);
break;
case 1:
((ImageButton) tabBtnFrd
.findViewById(R.id.btn_tab_bottom_friend))
.setImageResource(R.drawable.tab_find_frd_pressed);
break;
case 2:
((ImageButton) tabBtnAddress
.findViewById(R.id.btn_tab_bottom_contact))
.setImageResource(R.drawable.tab_address_pressed);
break;
case 3:
((ImageButton) tabBtnSettings
.findViewById(R.id.btn_tab_bottom_setting))
.setImageResource(R.drawable.tab_settings_pressed);
break;
}
currentIndex = position;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
protected void resetTabBtn() {
((ImageButton) tabBtnWeixin.findViewById(R.id.btn_tab_bottom_weixin))
.setImageResource(R.drawable.tab_weixin_normal);
((ImageButton) tabBtnFrd.findViewById(R.id.btn_tab_bottom_friend))
.setImageResource(R.drawable.tab_find_frd_normal);
((ImageButton) tabBtnAddress.findViewById(R.id.btn_tab_bottom_contact))
.setImageResource(R.drawable.tab_address_normal);
((ImageButton) tabBtnSettings.findViewById(R.id.btn_tab_bottom_setting))
.setImageResource(R.drawable.tab_settings_normal);
}
@Override
public void onEvent(int what, Bundle data, Object object) {
// TODO 自动生成的方法存根
mainHandler.sendEmptyMessage(what);
}
}
FragmentPagerAdapter刷新fragment最完美解决方案的更多相关文章
- Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案
原文地址:Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案 启用REWRITE的伪静态功能的时候,首页可以访问,而访问内页的时候,就提示:&quo ...
- 关于Entity Framework中的Attached报错的完美解决方案终极版
之前发表过一篇文章题为<关于Entity Framework中的Attached报错的完美解决方案>,那篇文章确实能解决单个实体在进行更新.删除时Attached的报错,注意我这里说的单个 ...
- No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案
No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案 首先这个问题的产生是由于缺少Theme.App ...
- ecshop之transport和jquery冲突之完美解决方案
众所周知:ecshop的transport.js文件和Jquery是冲突的,两个文件不能同时调用,现给出以下完美解决方案:原因分析:在transport.js文件中,大概 580行到590行之间,这个 ...
- Xcode6.1标准Framework静态库制作方法。工程转Framework,静态库加xib和图片。完美解决方案。
http://www.cocoachina.com/bbs/read.php?tid-282490.html Xcode6.1标准Framework静态库制作方法.工程转Framework,静态库加x ...
- Safari 前端开发调试 iOS 完美解决方案
转http://www.2cto.com/kf/201403/283404.html afari 前端开发调试 iOS 完美解决方案 2014-03-05 0个评论 来源:Safari ...
- C#多线程解决界面卡死问题的完美解决方案
C#多线程解决界面卡死问题的完美解决方案 文章转自http://www.sufeinet.com/thread-3556-1-1.html 问题描述: 当我们的界面需要在程序运行中不断更新数据时, 当 ...
- 完美解决方案,可排除DATASET不支持System.Nullable错误
完美解决方案,可排除DATASET不支持System.Nullable错误 using System; using System.Collections.Generic; using System.L ...
- Android消息推送完美解决方案全析
推送功能在手机应用开发中越来越重要,已经成为手机开发的必须.在Android应用开发中,由于众所周知的原因,Android消息推送我们不得不大费周折.本文就是用来和大家共同探讨一种Android消息推 ...
随机推荐
- C# 获得当前应用程序路径
1.获得当前应用程序的路径最稳定的方法:AppDomain.CurrentDomain.BaseDirectory 生成的路径:../项目名称/bin/Debug下的路径
- 我的一个关于RFID的项目总结
去年做的一个项目,今天在这里想总结一下,这是主要流程: [0]RFID(Reader)---->[1]网络---->[2]接收处理程序---->[3]队列---->[4]读/存 ...
- objective-C学习笔记(五)函数成员:初始化器和析构器
初始化器:init 对象初始化器: -(id)init 可以重载多个. 类型初始化器: +(id)initialize只能有一个. 对象初始化器: 初始化对象实例时,init通常和alloc(手动内存 ...
- Hadoop学习笔记(1)概述
写在学习笔记之前的话: 寒假已经开始好几天了,似乎按现在的时间算,明天就要过年了.在家的这几天,该忙的也都差不多了,其实也都是瞎忙.接下来的几点,哪里也不去了,静静的呆在家里学点东西.所以学习一下Ha ...
- ORA-12514(TNS:监听程序当前无法识别...)
记录: ORA-12514(TNS:监听程序当前无法识别...)的解决方案 在安装ORACLE 11G 过程中由于配置的原因,安装过程中报了如下错误: 按照安装提示执行后面的操作后,打开PL/SQ ...
- java中对象模型与数据库中的关系模型
实体类还需要配置到hibernate.cfg.xml中,以便Hibernate初始化实体类与数据库表的映射关系.如果只配置了映射关系,而没有配置到hibernate.cfg.xml中,Hibernat ...
- Android 开发笔记“Application 理解”
Android 中Application类用法 1. Application和Activity,Service一样是Android框架的一个系统组件,当Android程序启动时 ...
- Fedora 17配置ssh及Windows远程连接
转载自:http://nanjingjiangbiao-t.iteye.com/blog/1794213 Fedora 23 默认已经安装好openssh server了,不用再装不过默认情况下没有开 ...
- django FileFIeld和ImageField 上传路径改写
def get_file_path(instance, filename): return 'file/document/%s/%s/%s' % (instance.period.code, inst ...
- 基于FPGA的key button等开关消抖,按键消抖电路设计
最近要用上一个key消抖的功能.于是找到了之前写的并放入博客的程序,发现居然全部有问题.http://www.cnblogs.com/sepeng/p/3477215.html —— 有问题,包括很多 ...