Fragment禁止预加载

项目中经常会用到ViewPager+Fragment组合,然而,有一个很让人头疼的问题就是,去加载数据的时候由于ViewPager的内部机制所限制,所以它会默认至少预加载一个。

1、既然说是ViewPager的内部机制,那么我们可不可以设置ViewPager的预加载为0?如下:

vp.setOffscreenPageLimit(0);

No,结果发现根本行不通。。。查看源码:

   private static final int DEFAULT_OFFSCREEN_PAGES = 1;
    /**
     * Set the number of pages that should be retained to either side of the
     * current page in the view hierarchy in an idle state. Pages beyond this
     * limit will be recreated from the adapter when needed.
     *
     * <p>This is offered as an optimization. If you know in advance the number
     * of pages you will need to support or have lazy-loading mechanisms in place
     * on your pages, tweaking this setting can have benefits in perceived smoothness
     * of paging animations and interaction. If you have a small number of pages (3-4)
     * that you can keep active all at once, less time will be spent in layout for
     * newly created view subtrees as the user pages back and forth.</p>
     *
     * <p>You should keep this limit low, especially if your pages have complex layouts.
     * This setting defaults to 1.</p>
     *
     * @param limit How many pages will be kept offscreen in an idle state.
     */
    public void setOffscreenPageLimit(int limit) {
        if (limit < DEFAULT_OFFSCREEN_PAGES) {
            Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " + DEFAULT_OFFSCREEN_PAGES);
            limit = DEFAULT_OFFSCREEN_PAGES;
        }
        if (limit != mOffscreenPageLimit) {
            mOffscreenPageLimit = limit;
            populate();
        }
    }

所以即使你设置为0,还是会设置默认值1,所以这个方法是行不通的。

2、Fragment里面有个setUserVisibleHint(boolean isVisibleToUser)方法,所以考虑在此去处理数据。

 

public class LazyFragment extends Fragment {
    protected PullToRefreshListView mPullToRefreshListView;
    protected EmptyLayout mEmptyLayout;
    protected ListView mListView;
    protected int maxId = 0;
    //标志位,标志已经初始化完成
    protected boolean isInit = false;
    //是否已被加载过一次,第二次不再去请求数据
    protected boolean mHasLoadedOnce;
    private View view;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_common_list, null);
        initView(view);
        return view;
    }


    public void initView(View view) {
        mPullToRefreshListView = (PullToRefreshListView) view.findViewById(R.id.pull_refresh_list);
        mEmptyLayout = (EmptyLayout) view.findViewById(R.id.error_layout);
        isInit = true;
        isCanLoadData();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isCanLoadData();
    }

    /**
     * 禁止预加载
     */
    private void isCanLoadData() {
        if (!isInit) {
            return;
        }
        if (getUserVisibleHint() && !mHasLoadedOnce) {
            loadData();
        }
    }

    protected void loadData() {
    //数据加载成功后
    mHasLoadedOnce = true;
  }
}

 在loadData()中加载数据,在数据加载成功之后将mHasLoadedOnce置为true即可。以上完美解决因为Fragment的懒加载导致的,比如:预先请求服务器接口,造成服务器额外压力等问题~

   By LiYing

posted @ 2017-12-30 12:14  WidgetBox  阅读(2065)  评论(0编辑  收藏  举报