您的位置:首页 > 编程语言 > PHP开发

(4.3.1.13.1) FragmentPagerAdapter刷新fragment最完美解决方案

2015-09-11 15:35 621 查看


FragmentPagerAdapter刷新fragment最完美解决方案


先感谢kingjxl2006的博客文章《Android FragmentPagerAdapter数据刷新notifyDataSetChanged没效果研究》http://blog.sina.com.cn/s/blog_783ede03010173b4.html,没有他的抛砖引玉,就没有这篇博文。

好,切入正题,正如上文所说的那样,在fragmentpageadapter的instantiateItem方法里,他会先去FragmentManager里面去查找有没有相关的fragment如果有就直接使用如果没有才会触发fragmentpageadapter的getItem方法获取一个fragment。所以你更新fragments集合是没有作用的。引用kingjxl2006的文章里的代码如下:

// Do we already have this fragment?

String name = makeFragmentName(container.getId(), position);

Fragment fragment = mFragmentManager.findFragmentByTag(name);

if (fragment != null) {

if (DEBUG) Log.v(TAG, "Attaching item #" + position + ": f=" + fragment);

mCurTransaction.attach(fragment);

} else {

fragment = getItem(position);

if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);

mCurTransaction.add(container.getId(), fragment,

makeFragmentName(container.getId(), position));

}


kingjxl2006的办法是清除FragmentManager里面全部缓存的fragment。这很暴力我不赞同,全部清除会造成fragment重新加载,造成不必要的性能损失。

这个方案还是在instantiateItem方法里作文章,代码如下:

@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文章里的两条代码:

String name = makeFragmentName(container.getId(), position);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
说明fragmentpageadapter内部是用tag识别fragment的,并且有它自己的一套算法用于生成tag,所以我们这里必须用它生成的tag来添加新的fragment,否则fragmentpageadapter就无法识别这个新的fragment。
fragmentsUpdateFlag如其名,是一个用来标识哪个fragment需要更新的boolean类型的数组。
很多网友提问fm是什么东西?其实就是一个FragmentManager,在构造的时候传入即可:
class MyFragmentPagerAdapter extends FragmentPagerAdapter {

FragmentManager fm;

MyFragmentPagerAdapter(FragmentManager fm) {

super(fm);

this.fm = fm;

}

……

下面贴完整一点的代码,以照顾新同学们:
package com.example.mainframework03;

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);

}

}

我的这个例程是在鸿洋_大大(/article/1345566.html)的基础上改来的,再此感谢鸿洋_大大。

下载源码http://download.csdn.net/download/z13759561330/8114191
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: