项目中Viewpager+fragment应该是经常用到的。Viewpager默认是会加载当前可见的fragment和当前左右各一个fragment,如果有需求fragment第一次可见再加载界面的话,就需要我们对fragment做一些修改了。
/**
* 针对配合viewPager使用的fragment做了懒加载处理,只有第一次可见的时候才初始化UI界面
*/
public abstract class LazyViewPagerBaseFragment extends BaseFragment{
private boolean isShowing = false;
private boolean isFirstShow = true;//是否首次展示(首次的定义包含不回调onCreate方法,而回调onCreateView方法。此时fragment中已经初始化了的的变量字段是有值的,如adapter和数据list)
protected abstract void onFragmentFirstShow();
/**
* 界面已经加载出来的fragment之间切换
*/
protected abstract void onFragmentChange(boolean isVisible);
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isShowing = isVisibleToUser;
if (!isShowing && getView() == null){
isFirstShow = true;
} else if (isShowing && !isFirstShow && getView() != null){
//viewpager 切换
onFragmentChange(isShowing);
}else if (isShowing && isFirstShow && getView() != null){
onFragmentFirstShow();
isFirstShow = false;
}
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (isShowing && isFirstShow){
//首次显示
onFragmentFirstShow();
isFirstShow = false;
}
}
}
上面是我针对项目中的BaseFragment做的修改,需要懒加载的fragment继承这个LazyViewPagerBaseFragment就可以了。其中onFragmentFirstShow()这个方法就是fragment第一次可见时候的回调,onFragmentChange(boolean isVisible)这个是已经加载界面的fragment在viewpager滑动的时候可见与不可见的回调。
需要注意的点:
在onFragmentFirstShow()方法中初始化了的当前fragment中的数据,如果次fragment被viewpager销毁之后再次可见,这些数据还是有值的。比如,fragment中有一个List数组,这个list是在onFragmentFirstShow()中赋值的,那么当这个fragment被滑动viewpager销毁又可见的话,这个list中还是有值的。要注意数据的重复,可以加个判断,如果list已经有值了,就不再赋值。实际上滑动viewpager销毁的fragment,只是销毁了其中的view。fragment的onCreate()方法不会再次回调,而是会回调onCreateView(), onViewCreated()等。
这里补充说明一下上面说的销毁和可见,默认情况下,viewpager中三个fragmentA,B,C。当滑动到fragmentC可见的时候,fragmentA是销毁了的。
下面是我在项目中的应用
public class RankingViewPagerFragment extends LazyViewPagerBaseFragment {
private static final String TAG = "RankingViewPagerFragment";
@BindView(R.id.ranking_list_tablayout)
SlidingTabLayout mTabLayout;
@BindView(R.id.ranking_list_viewpager)
ViewPager mViewPager;
private String RANKING_TYPE = "RANKING_TYPE";//排行榜类型
private String mRankingType = "";
private RankingViewPageAdapter mViewPageAdapter;
private String[] mTabTitle;
private List<RankingListFragment> mFragmentList = new ArrayList<>();
public static RankingViewPagerFragment newInstance(String type) {
RankingViewPagerFragment fragment = new RankingViewPagerFragment();
Bundle bundle = new Bundle();
bundle.putString(fragment.RANKING_TYPE, type);
fragment.setArguments(bundle);
return fragment;
}
/**
* 此方法是项目中baseFragment中的抽象方法,是在onCreate中调用的,等同于onCreate
* @return
*/
@Override
protected int getLayoutId() {
return R.layout.fragment_ranking_view_pager;
}
/**
* fragment首次可见
*/
@Override
protected void onFragmentFirstShow() {
initView();
}
@Override
protected void onFragmentChange(boolean isVisible) {
//已经加载出来的fragment可见与不可见的回调
}
private void initView() {
Bundle bundle = getArguments();
if (bundle != null) {
mRankingType = bundle.getString(RANKING_TYPE);
}
mTabTitle = getResources().getStringArray(R.array.contribute_list_table);
//这里判断是为了防止数据重复
if (mFragmentList.size() == 0){
mFragmentList.add(RankingListFragment.newInstance(mRankingType, RankingListFragment.DAY_RANKING));
mFragmentList.add(RankingListFragment.newInstance(mRankingType, RankingListFragment.WEEK_RANKING));
mFragmentList.add(RankingListFragment.newInstance(mRankingType, RankingListFragment.MOTH_RANKING));
}
//同样的这里判断是为了不重复new对象
if (mViewPageAdapter == null){
mViewPageAdapter = new RankingViewPageAdapter(getChildFragmentManager(), mTabTitle, mFragmentList);
}
if (mViewPager != null) {
mViewPager.setAdapter(mViewPageAdapter);
if (mTabLayout != null) {
mTabLayout.setViewPager(mViewPager);
}
}
}
}