項(xiàng)目需求似忧,如下圖
實(shí)現(xiàn)方法
主MainActivity 承載5個(gè)fragment,對(duì)應(yīng)著下面5個(gè)按鈕進(jìn)行切換丈秩,該處使用的fragment的add與hide方法同時(shí)加載盯捌,調(diào)用方法如下:
private void showFragment(Fragment targetFragment) {
//如果當(dāng)前fragment和目標(biāo)fragment一致
if (targetFragment == currentFragment) {
return;
}
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (currentFragment != null) {
ft.hide(currentFragment);
}
if (targetFragment.isAdded()) {
//如果目標(biāo)已被添加,直接顯示即可
ft.show(targetFragment);
} else {
//如果未被添加蘑秽,則需添加后顯示
ft.add(R.id.framelayout, targetFragment).show(targetFragment);
}
ft.commitAllowingStateLoss();
currentFragment = targetFragment;
}
而首頁(yè)界面對(duì)應(yīng)的是多個(gè)不同tab饺著,用ViewPager 承載fragment進(jìn)行實(shí)現(xiàn),開(kāi)始的時(shí)候使用原始FragmentPagerAdapter,只重寫(xiě)了
@Override
public Fragment getItem(int i) {
return mFragmentList.get(i);
}
@Override
public int getCount() {
return mFragmentList == null ? 0 : mFragmentList.size();
}
并在首頁(yè)fragment創(chuàng)建的時(shí)候調(diào)用
mHomePagerAdapter = new FragmentAdapter(getChildFragmentManager(), mFragmentList);
viewPager.setAdapter(mHomePagerAdapter);
viewPager.setCurrentItem(0);
magicIndicator.onPageSelected(0);
收到數(shù)據(jù)回調(diào)的時(shí)候肠牲,重新如下處理:
@Override
public void getUserTypesSuccess(List<TemplateTypeModel> list) {
mTemplateTypeModels = list;
Collections.sort(mTemplateTypeModels, (o1, o2) -> o1.getTypeOrder() - o2.getTypeOrder());
mCommonNavigatorAdapter.notifyDataSetChanged();
if (mFragmentList == null) mFragmentList = new ArrayList<>();
mFragmentList.clear();
for (TemplateTypeModel model : list) {
mFragmentList.add(TypeListFragment.newInstance(model));
}
mHomePagerAdapter.notifyDataSetChanged();
}
問(wèn)題
界面未收到刷新(這里有個(gè)注意點(diǎn)幼衰,在fragment里承載viewpager要使用getChildFragmentManager)
修改方式:
懷疑為緩存問(wèn)題,實(shí)際也正是viewpager緩存問(wèn)題
嘗試拿到數(shù)據(jù)缀雳,重新設(shè)置adapter
@Override
public void getUserTypesSuccess(List<TemplateTypeModel> list) {
mTemplateTypeModels = list;
Collections.sort(mTemplateTypeModels, (o1, o2) -> o1.getTypeOrder() - o2.getTypeOrder());
mCommonNavigatorAdapter.notifyDataSetChanged();
if (mFragmentList == null) mFragmentList = new ArrayList<>();
mFragmentList.clear();
for (TemplateTypeModel model : list) {
mFragmentList.add(TypeListFragment.newInstance(model));
}
mHomePagerAdapter = new FragmentAdapter(getChildFragmentManager(), mFragmentList);
viewPager.setAdapter(mHomePagerAdapter);
viewPager.setCurrentItem(0);
magicIndicator.onPageSelected(0);
}
問(wèn)題
運(yùn)行發(fā)現(xiàn)更新的時(shí)候渡嚣,可以正常更新數(shù)據(jù),等等肥印,增刪list 數(shù)量的時(shí)候识椰,發(fā)現(xiàn)viewpager中fragment 展示的界面和實(shí)際期望的界面不一樣,莫非還是緩存問(wèn)題深碱,上網(wǎng)經(jīng)過(guò)一番腹鹉,需要設(shè)置adapter 中
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
修改
加入之后,發(fā)現(xiàn)效果不明顯敷硅,繼續(xù)百度功咒,有人說(shuō)要?jiǎng)h除fragmentmanager中的fragment,好吧绞蹦,加入力奋,看一下,繼續(xù)修改
@Override
public void getUserTypesSuccess(List<TemplateTypeModel> list) {
List<Fragment> olds = getChildFragmentManager().getFragments();
if (olds != null) {
FragmentTransaction ft = getChildFragmentManager().beginTransaction();//獲得FragmentTransaction 事務(wù)
for (Fragment f : olds) {
ft.remove(f); //遍歷刪除fragment
}
ft.commit();
getChildFragmentManager().executePendingTransactions();
}
mTemplateTypeModels = list;
Collections.sort(mTemplateTypeModels, (o1, o2) -> o1.getTypeOrder() - o2.getTypeOrder());
mCommonNavigatorAdapter.notifyDataSetChanged();
if (mFragmentList == null) mFragmentList = new ArrayList<>();
mFragmentList.clear();
for (TemplateTypeModel model : list) {
mFragmentList.add(TypeListFragment.newInstance(model));
}
mHomePagerAdapter = new FragmentAdapter(getChildFragmentManager(), mFragmentList);
viewPager.setAdapter(mHomePagerAdapter);
viewPager.setCurrentItem(0);
magicIndicator.onPageSelected(0);
}
運(yùn)行坦辟,完美解決問(wèn)題刊侯,不過(guò)總感覺(jué)不夠優(yōu)雅
使用FragmentStatePagerAdapter
由于FragmentPagerAdapter和FragmentStatePagerAdapter內(nèi)部緩存機(jī)制不一樣,F(xiàn)ragmentStatePagerAdapter是直接銷毀fragment锉走,而不是復(fù)用,具體區(qū)別可以參考 FragmentPagerAdapter與FragmentStatePagerAdapter區(qū)別
viewPager.setAdapter(mHomePagerAdapter = new FragmentStatePagerAdapter(getChildFragmentManager()) {
@Override
public int getCount() {
return mFragmentList == null ? 0 : mFragmentList.size();
}
@Override
public Fragment getItem(int i) {
return mFragmentList.get(i);
}
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
});
這里可以直接使用notifyDataSetChanged進(jìn)行界面的刷新
@Override
public void getUserTypesSuccess(List<TemplateTypeModel> list) {
mTemplateTypeModels = list;
Collections.sort(mTemplateTypeModels, (o1, o2) -> o1.getTypeOrder() - o2.getTypeOrder());
mCommonNavigatorAdapter.notifyDataSetChanged();
if (mFragmentList == null) mFragmentList = new ArrayList<>();
mFragmentList.clear();
for (TemplateTypeModel model : list) {
mFragmentList.add(TypeListFragment.newInstance(model));
}
mHomePagerAdapter.notifyDataSetChanged();
viewPager.setCurrentItem(0);
magicIndicator.onPageSelected(0);
}
總結(jié):
遇到viewpager 使用fragment藕届,界面不刷新的問(wèn)題挪蹭,可以考慮使用FragmentStatePagerAdapter,并重寫(xiě)
@Override
public int getItemPosition(@NonNull Object object) {
return POSITION_NONE;
}
然后就和使用listview等數(shù)據(jù)刷新行為一致了