Back

android - 让fragment延迟加载

发布时间: 2017-08-12 04:11:00

参考:   https://github.com/linglongxin24/ViewPagerFragmentLazyLoad

具体步骤: 

1. 对于已经存在的fragment, 如果该fragment之前会打开webview, 那么,现在要把这个方法注释掉. 如下: 

// loadWebView()...

2. 对于所有的Fragment, 可以建立一个Fragment基础类, 如下 ;

public abstract class BaseWebViewFragment extends BaseFragment {

    /**
     * 该fragment的实例是否被创建,  在初始化方法中控制
     */
    private boolean isInitialized = false;

    /**
     * 该fragment 当前是否可见(显示给用户), adapter?
     */
    private boolean isVisible = false;

    /**
     * 该fragment 是否已经加载了
     */
    private boolean isLoaded = false;

    public static String TAG = "BaseWebViewFragment";

    protected AppWebView webview;

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        isInitialized = true;
        lazyLoad();
    }

    /**  该方法用于 "尝试" 延迟加载. 如果已经加载了的话, 该页面就不动了.
    */
    public void lazyLoad() {
        if (!isLoaded && isInitialized && isVisible) {
            Log.d(TAG, "== now lazyLoad the fragment");
            isLoaded = true;
            loadWebPage();
        }
    }

    /**
     * 这个方法用于决定当前的 fragment 应该跳转到哪里.  所有的子类都应该实现这个方法
     */
    public abstract void loadWebPage();

    /** 该方法是在 每次 "三个fragment 组成的view pager" 左右滑动 的时候,会自动调用这个方法. 
       另外,该方法也会在 "三个fragment组成的view pager"首次被Activity载入的时候调用.

       每次有一个fragment滑动时, 两个fragment的该方法都会被调用:  一个是离开主屏幕的,一个是即将进入主屏幕的.    
    */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
//        Log.d(TAG, "== called setUserVisibleHint");
        Log.d(TAG, " lazyLoad: isInitialized: " + String.valueOf(isInitialized)
                + ", isVisible: " + String.valueOf(isVisible) + ", isLoaded: " + String.valueOf(isLoaded)
        );
        isVisible = isVisibleToUser;
        lazyLoad();
    }

   /// 其他代码...
}

然后, 这个文章中,提到了fragment 的声明周期,非常有用. 如下: ( http://blog.csdn.net/biezhihua/article/details/50235693 )

前言

根据ViewPager+Frgment的小例子,来研究Fragment生命周期方法与Fragment视图是否可见间的细节。

正文

所用资源:ViewPager+Fragment,ViewPager只默认预加载1页,共三个Fragment。

动作1:执行App,界面显示

//PlaceholderFragment: 1 setUserVisibleHint() called with: isVisibleToUser = [false]
//PlaceholderFragment: 2 setUserVisibleHint() called with: isVisibleToUser = [false]
//PlaceholderFragment: 1 onAttach() called with: 
//PlaceholderFragment: 1 onCreate() called with: 
//PlaceholderFragment: 1 setUserVisibleHint() called with: isVisibleToUser = [true]
//PlaceholderFragment: 1 onCreateView() called with:
//PlaceholderFragment: 1 onViewCreated() called with:
//PlaceholderFragment: 1 onActivityCreated() called with:
//PlaceholderFragment: 1 onStart() called with:
//PlaceholderFragment: 1 onResume() called with:
//PlaceholderFragment: 2 onAttach() called with: 
//PlaceholderFragment: 2 onCreate() called with: 
//PlaceholderFragment: 2 onCreateView() called with:
//PlaceholderFragment: 2 onViewCreated() called with:
//PlaceholderFragment: 2 onActivityCreated() called with:
//PlaceholderFragment: 2 onStart() called with:
//PlaceholderFragment: 2 onResume() called with:

首先,会调用前两页的setUserVisibleHint()方法并设置为false,表明两个Fragmnet所代表的视图,还尚未显示。

接着执行Fragment1的生命周期流程,并在onCreate()与onCreateView()之间执行setUserVisbleHint()为true,来表示Fragment1已用户可见。

随后执行Fragment2的生命周期流程,直至onResume()被调用。但是此时Fragment2还处于用户不可见状态。

动作2:滑动到第二个Fragment

//PlaceholderFragment: 3 setUserVisibleHint() called with: isVisibleToUser = [false]
//PlaceholderFragment: 1 setUserVisibleHint() called with: isVisibleToUser = [false]
//PlaceholderFragment: 2 setUserVisibleHint() called with: isVisibleToUser = [true]
//PlaceholderFragment: 3 onAttach() called with:
//PlaceholderFragment: 3 onCreate() called with:
//PlaceholderFragment: 3 onCreateView() called with:
//PlaceholderFragment: 3 onViewCreated() called with:
//PlaceholderFragment: 3 onActivityCreated() called with:
//PlaceholderFragment: 3 onStart() called with:
//PlaceholderFragment: 3 onResume() called with:

首先,执行3个Fragment的setUserVisbleHint()方法,去表明Fragment是否为可见状态。此时,Fragment2处于可见状态,Fragment1和预加载的Fragment3处于不可见状态。

紧接着再去执行Fragment3的生命周期方法。

动作3:滑动到第三个Fragment

//PlaceholderFragment: 2 setUserVisibleHint() called with: isVisibleToUser = [false]
//PlaceholderFragment: 3 setUserVisibleHint() called with: isVisibleToUser = [true]
//PlaceholderFragment: 1 onPause() called with:
//PlaceholderFragment: 1 onStop() called with:
//PlaceholderFragment: 1 onDestroyView() called with:

首先,先执行当前Fragment和缓存Fragmnet2的setUserVisibleHint()方法,表明各自的可见状态,此时,Fragment3处于可见状态。

紧接着去释放Fragment1的视图资源,但并不销毁Fragment1

结论

Fragment和Activity的大部分生命周期绑定在一起,但是Fragment的onResume()并不意味着Fragment对于用户可见,真正Fragment对用户可见会执行的方法是setUserVisbleHInt()并且为true时。

在Fragment的声明周期中,setUserVisbleHint()方法会被调用两次,第一次是在Fragment声明周期尚未开始时,用于初始化userVisbleHint变量;第二次实在onCreate()与onCreateView()之间调用,表明Fragment已经处于可见状态。

Back