Fragement+viewPager片段刷新的一种解决方案
最近在做一个小的app时遇到了一个关于fragement片段刷新的问题,自己不会,百度发现好多人也遇到了同样的问题,解决方案也有很多,比如全局广播,intent方式,接口回调,抽象内部类等等,但是感觉作为一个新手,表示不太会会广播,而且广播的话不好写,毕竟不同的页面可能存在不同的更新,如果页面很多就GG了,还不可以带数据。。。。嗯嗯,说错了,可能我真不懂广播。回到正题:
我的解决方案其实很简单:直接在适配器里面自定义刷新方法,Activity里面调用就是。直接看核心代码:
/**
* 缓存清理函数,实现片段的定向刷新,适用于数据影响的(fragement)片段范围为比较小的操作,比如添加账户后的单个片段的刷新
* @param position 要更新的fragement在fragments列表的相对位置
* @param newFragment 新的片段
*/
public void setFragments(Integer position,Fragment newFragment){
FragmentTransaction ft = fm.beginTransaction();//开启事务
/*
* 获取第position个的id,适配器是通过这个id来找到相应片段的
*/
Integer id = this.fragments.get(position).getId();
/**
* 替换缓存中的片段,可以用replace实现,当然也可以用如下方法
*/
ft.remove(this.fragments.get(position));
ft.add(id, newFragment);
/**
* 更新片段列表
*/
this.fragments.add(position,newFragment);
/**
* 别忘了提交就是
*/
ft.commit();
ft = null;
fm.executePendingTransactions();
/**
* 通知适配器数据改变
*/
notifyDataSetChanged();
}
/*这个也别忘了
*/
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
思路就是:自定义方法,通过FragementTransaction开启一个事务,用于操作adapther缓存片段,以及片段列表。在Activity定义一个adapther,直接通过adapther.setFragement(参数...);
用到的知识点:
Fragment 事务管理
FragmentManager 功能 : FragmentManager 对象 可以通过 activity.getFragmentManager()获取;
获取指定 Fragment : 通过 findFragmentById() 或者 findFragmentByTag() 方法获取指定 Fragment;
弹出栈 : 通过调用 popBackStack(), 将 Fragment 从后台的 栈 中弹出;
监听栈 : 通过调用 addOnBackStackChangeListener 注册监听器, 监听 后台栈变化;
FragmentTransaction 对象获取途径 :
获取 FragmentManager 对象 : 调用 Activity 的 getFragmentManager() 获取 FragmentManager 对象;
获取 FragmentTansaction 对象 : 调用 FragmentManager 对象的 beginTransaction() 方法获取 FragmentTransaction 对象;
FragmentTransaction(Fragment 事务)作用 : 对 Fragement 进行 增, 删 , 改 操作需要 FragmentTransaction 对象进行操作, 开启 这个事务, 获取 事务对象, 然后执行对 Fragment 的操作, 最后提交事务;
开启事务 : 调用 Fragement 对象的beginTransaction() 方法可以获取 FragementTransaction 对象;
操作碎片 : FragmentTransaction 对象 中 包含了add(), remove(), replace() 等方法;
提交操作 : 当执行完 Fragement 的操作之后, 可以调用 FragementTransaction 对象的commit() 方法提交修改;
addToBackStack()方法作用 : 该方法是 FragementTransaction 的方法, 在提交事务前调用该方法, 可以将 事务中执行的操作 添加到 back 栈中, 用户按下 回退键,修改过的 Fragement 会 回退到 事务执行之前的状态;
全部代码:
适配器
package com.money.adapter;
import java.util.ArrayList;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
public class MainVpAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments;
private FragmentManager fm;//fragement管理
public MainVpAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
this.fm = fm;
this.fragments = fragments;
}
/**
* 缓存清理函数,实现全部刷新,适用于数据影响为比较大的操作,比如登录后实现所有片段的刷新
* @param fragments 新的fragements列表
*
*/
public void setFragments(ArrayList<Fragment> fragments) {
if (this.fragments != null) {
FragmentTransaction ft = fm.beginTransaction();
for (Fragment f : this.fragments) {
ft.remove(f);
}
ft.commit();
ft = null;
fm.executePendingTransactions();
}
this.fragments = fragments;
notifyDataSetChanged();
}
/**
* 缓存清理函数,实现片段的定向刷新,适用于数据影响的(fragement)片段范围为比较小的操作,比如添加账户后的单个片段的刷新
* @param position 要更新的fragement在fragments列表的相对位置
* @param newFragment 新的片段
*/
public void setFragments(Integer position,Fragment newFragment){
FragmentTransaction ft = fm.beginTransaction();
/*
* 获取第position个的id,适配器是通过这个id来找到相应片段的
*/
Integer id = this.fragments.get(position).getId();
/**
* 替换缓存中的片段,可以用replace实现,当然也可以用如下方法
*/
ft.remove(this.fragments.get(position));
ft.add(id, newFragment);
/**
* 更新片段列表
*/
this.fragments.add(position,newFragment);
/**
* 别忘了提交
*/
ft.commit();
ft = null;
fm.executePendingTransactions();
/**
* 通知适配器数据改变
*/
notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Fragment getItem(int arg0) {
return fragments.get(arg0);
}
@Override
public int getCount() {
return fragments.size();
}
}
调用方法:
/**
* 刷新片段的布局
*
* @param position
*/
public void flush(int position) {
this.mFragments.remove(position);
Fragment newfragement = null;
switch (position) {
case 0:
newfragement = new ChargeFragment();
break;
case 1:
newfragement = new ReportSheetFragment();
break;
case 2:
newfragement = new CapitalFragment();
break;
case 3:
newfragement = new MoreFragment();
break;
}
this.mFragments.add(position, newfragement);
//this.mFragments.add(this.mFragments);
adapter.setFragments(position,newfragement);
}