Fragment + FragmentPagerAdapter的懒加载

FragmentPagerAdapter主要看思想

FragmentPagerAdapter执行流程,暂且说是生命周期吧
可以去ViewPage的populate()方法中查看
startUpdate() -> instantiateItem() ->destroyItem()->setPrimaryItem()->finishUpdate()
在ViewPage源码addNewItem()中调用instantiateItem()方法

接下来我们去看FragmentPageAdapter的源码中instantiateItem()方法做了什么
FragmentTransaction 如果不熟悉Fragment的生命周期和FragmentTransaction的主要方法

  public Object instantiateItem(@NonNull ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final long itemId = getItemId(position);

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
           // 主要在这里 !!!!!
            if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
            	// Lifecycle.State.STARTED 创建并启动,可见不可操作 就是onStarted()方法
                mCurTransaction.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
            } else {
            	//旧的
                fragment.setUserVisibleHint(false);
            }
        }

        return fragment;
    }

知道了这里基本上就可以实现懒加载了
我是这样写的
首先在BaseFragment中

 @Override
    public void onStart() {
        super.onStart();
        loadData();
    }
    protected void loadData() {    //网络数据加载
    }
   

这里的话很多人都是在onResume方法中去进行懒加载看个人吧,也可以用之前旧的写法在这里旧不说明了
这里我写一个示例

 private boolean isFirstLoad = true; // 是否第一次加载
  	@Override
	public void onResume(){
		if(isFirstLoad){
			isFirstLoad = false;
			loadData();
		}
		protected void loadData() {    //网络数据加载 }
 	}

然后在子类中

public class NewsFragment extends CoyoteFragment<NewsPresenter, NewsModel> implements NewsContract.View {
    private String type;
    @BindView(R.id.rlv_news)
    RecyclerView mRecyclerView;
    private NewsAdapter adapter;
    @BindView(R.id.refreshLayout)
    RefreshLayout mRefreshLayout;   //刷新框架
    private int page = 1;
    private int pageSize = 20;
    private List newsData;  //数据源
    private boolean isFirstResume = false;  //第一次进入
    /**
     * 获取Fragment实例
     *
     * @param type 类型
     * @return NewsFragment
     */
    public static NewsFragment getInstance(String type) {
        Bundle bundle = new Bundle();
        bundle.putString(VALUE_TYPE, type);
        NewsFragment newsFragment = new NewsFragment();
        newsFragment.setArguments(bundle);
        return newsFragment;
    }

    @Override
    protected int getLayoutId() {
        Bundle bundle = getArguments();
        if (bundle != null) {
            type = bundle.getString(VALUE_TYPE);
        } else {
            throw new NullPointerException("request type not null");
        }
        return R.layout.fragment_news;
    }

    @Override
    protected void initData() {
        adapter = new NewsAdapter(getContext());
        mRecyclerView.setLayoutManager(new LinearLayoutManager(MyApplication.getInstance(), LinearLayoutManager.VERTICAL, false));
        //下拉刷新监听
        mRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                mMvpPresenter.getRefreshNews(type, 1, pageSize,
                        NewsContract.Presenter.RefreshState.REFRESH);
            }
        });
        //上拉加载监听
        mRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
                mMvpPresenter.getRefreshNews(type, ++page, pageSize,
                        NewsContract.Presenter.RefreshState.LOADMORE);
            }
        });
    }

    /**
     * 数据渲染
     */
    @Override
    public void onResume() {
        super.onResume();
        //已经存在请求回来数据
        if(this.newsData != null && !isFirstResume){
            if(this.newsData.size() > 0){
                Log.i("NewsFragment", "onResume: " + type);
                isFirstResume = true;
                adapter.setDatas(newsData);
                mRecyclerView.setAdapter(adapter);
            }
        }
    }

    /**
     * 请求网络数据
     */
    @Override
    protected void loadData() {
        mMvpPresenter.getNews(type, page, pageSize);
    }

    /**
     * 拿到数据源并且在onResumed的时候就直接重新刷新数据
     * 因为我这里使用的是局部刷新就没调用notifyDataSetChanged()方法
     * 具体的话可以去了解 AsyncListDiffer
     * @param news
     */
    @Override
    public void refreshData(List news) {
        this.newsData = news;
        if(isResumed()){
            Log.i("NewsFragment", "refreshData: " + type);
            adapter.setDatas(newsData);
            mRecyclerView.setAdapter(adapter);
        }
    }

    @Override
    public RefreshLayout finishRefresh(int delayed, boolean success, Boolean noMoreData, NewsPresenter.RefreshState refreshState) {
        if (refreshState == NewsPresenter.RefreshState.REFRESH) {
            return mRefreshLayout.finishRefresh(delayed, success, noMoreData);
        } else if (refreshState == NewsPresenter.RefreshState.LOADMORE) {
            return mRefreshLayout.finishLoadMore(delayed, success, noMoreData);
        }
        return null;
    }
}

在mainFragment中我是使用TabLayout+Fragment的方式
只需要在初始化Adapter的时候传BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT就ok

adapter = new HomeViewPageAdapter(titles, getChildFragmentManager(), FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xpq_lrh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值