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