Android Fragment延迟加载(仿微信的Viewpager-Fragment惰性加载)

Home / Android MrLee 2016-10-24 3624

Android Fragment延迟加载(仿微信的Viewpager-Fragment惰性加载)

1477024003379.gif

我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载!

那么在这个activity刚创建的时候就变成需要初始化大量资源,请求很多接口,这样的结果,我们当然不会满意。那么,能不能做到当切换到这个fragment的时候,它才去初始化呢?

ok 那就如图 我们展示一下 源代码 :

MainActivity MyFragmentPagerAdapter

MoreFragment继承》LazyFragment 继承》父类BaseFragment

  • MainActivity 这是平时 我们viewpager 配合fragment 的使用方法 我们新建工程的时候 9成都会用到此方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<code>public class MainActivity extends AppCompatActivity {<br>    @InjectView(R.id.viewPager2)
    ViewPager viewPager;
    private List<Fragment> fragmentList;<br>    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        fragmentList = new ArrayList<>();
        fragmentList.add(MoreFragment.newInstance(1,false));
        fragmentList.add(MoreFragment.newInstance(2,true));
        fragmentList.add(MoreFragment.newInstance(3,true));
        fragmentList.add(MoreFragment.newInstance(4,true));
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(supportFragmentManager, fragmentList);
        viewPager.setAdapter(myFragmentPagerAdapter);
        viewPager.setOffscreenPageLimit(4);
    }<br>     class MyFragmentPagerAdapter extends FragmentPagerAdapter {
        private List<Fragment> fragmentList;<br>        public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {
            super(fm);
            this.fragmentList = fragmentList;
        }<br>        @Override
        public Fragment getItem(int position) {
            return fragmentList.get(position);
        }<br>        @Override
        public int getCount() {
            return fragmentList.size();
        }<br>    }<br>}</code>
  • MoreFragment 这就是我们正常创建的fragment 和以往不同的是:

    onCreateView 方法 变成了 onCreateViewLazy

    并且 多了一个newInstance方法

1
2
3
4
5
6
7
8
9
10
11
12
13
<code>public class MoreFragment extends LazyFragment {<br>    public static final String INTENT_INT_INDEX="index";
    public static MoreFragment newInstance(int tabIndex,boolean isLazyLoad) {<br>        Bundle args = new Bundle();
        args.putInt(INTENT_INT_INDEX, tabIndex);
        args.putBoolean(LazyFragment.INTENT_BOOLEAN_LAZYLOAD, isLazyLoad);
        MoreFragment fragment = new MoreFragment();
        fragment.setArguments(args);
        return fragment;
    }
    @Override
    protected void onCreateViewLazy(Bundle savedInstanceState) {
        super.onCreateViewLazy(savedInstanceState);
        setContentView(R.layout.fragment_tabmain_item);<br>    }
}</code>
  • LazyFragment

懒加载Fragment 只有创建并显示的时候才会调用onCreateViewLazy方法

  • 懒加载的原理onCreateView的时候Fragment有可能没有显示出来。
  • 但是调用到setUserVisibleHint(boolean isVisibleToUser),isVisibleToUser =

    true的时候就说明有显示出来

  • 但是要考虑onCreateView和setUserVisibleHint的先后问题所以才有了下面的代码

《1》原先的Fragment的回调方法名字后面要加个Lazy,比如Fragment的onCreateView方法, 就写成onCreateViewLazy

《2》使用该LazyFragment会导致多一层布局深度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<code>public class LazyFragment extends BaseFragment {
    private boolean isInit = false;//真正要显示的View是否已经被初始化(正常加载)
    private Bundle savedInstanceState;
    public static final String INTENT_BOOLEAN_LAZYLOAD = "intent_boolean_lazyLoad";
    private boolean isLazyLoad = true;
    private FrameLayout layout;
    private boolean isStart = false;//是否处于可见状态,in the screen<br>    @Override
    protected final void onCreateView(Bundle savedInstanceState) {
        Log.d("TAG", "onCreateView() : " + "getUserVisibleHint():" + getUserVisibleHint());
        super.onCreateView(savedInstanceState);
        Bundle bundle = getArguments();
        if (bundle != null) {
            isLazyLoad = bundle.getBoolean(INTENT_BOOLEAN_LAZYLOAD, isLazyLoad);
        }
        //判断是否懒加载
        if (isLazyLoad) {
            //一旦isVisibleToUser==true即可对真正需要的显示内容进行加载
            if (getUserVisibleHint() && !isInit) {
                this.savedInstanceState = savedInstanceState;
                onCreateViewLazy(savedInstanceState);
                isInit = true;
            } else {
                //进行懒加载
                layout = new FrameLayout(getApplicationContext());
                layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.fragment_lazy_loading, null);
                layout.addView(view);
                super.setContentView(layout);
            }
        } else {
            //不需要懒加载,开门江山,调用onCreateViewLazy正常加载显示内容即可
            onCreateViewLazy(savedInstanceState);
            isInit = true;
        }
    }<br>    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        Log.d("TAG", "setUserVisibleHint() called with: " + "isVisibleToUser = [" + isVisibleToUser + "]");
        //一旦isVisibleToUser==true即可进行对真正需要的显示内容的加载<br>        //可见,但还没被初始化
        if (isVisibleToUser && !isInit && getContentView() != null) {
            onCreateViewLazy(savedInstanceState);
            isInit = true;
            onResumeLazy();
        }
        //已经被初始化(正常加载)过了
        if (isInit && getContentView() != null) {
            if (isVisibleToUser) {
                isStart = true;
                onFragmentStartLazy();
            } else {
                isStart = false;
                onFragmentStopLazy();
            }
        }
    }<br>    @Override
    public void setContentView(int layoutResID) {
        //判断若isLazyLoad==true,移除所有lazy view,加载真正要显示的view
        if (isLazyLoad && getContentView() != null && getContentView().getParent() != null) {
            layout.removeAllViews();
            View view = inflater.inflate(layoutResID, layout, false);
            layout.addView(view);
        }
        //否则,开门见山,直接加载
        else {
            super.setContentView(layoutResID);
        }
    }<br>    @Override
    public void setContentView(View view) {
        //判断若isLazyLoad==true,移除所有lazy view,加载真正要显示的view
        if (isLazyLoad && getContentView() != null && getContentView().getParent() != null) {
            layout.removeAllViews();
            layout.addView(view);
        }
        //否则,开门见山,直接加载
        else {
            super.setContentView(view);
        }
    }<br>    @Deprecated
    @Override
    public final void onStart() {
        Log.d("TAG", "onStart() : " + "getUserVisibleHint():" + getUserVisibleHint());
        super.onStart();
        if (isInit && !isStart && getUserVisibleHint()) {
            isStart = true;
            onFragmentStartLazy();
        }
    }<br>    @Deprecated
    @Override
    public final void onStop() {
        super.onStop();
        Log.d("TAG", "onStop() called: " + "getUserVisibleHint():" + getUserVisibleHint());
        if (isInit && isStart && getUserVisibleHint()) {
            isStart = false;
            onFragmentStopLazy();
        }
    }<br>    //当Fragment被滑到可见的位置时,调用
    protected void onFragmentStartLazy() {
        Log.d("TAG", "onFragmentStartLazy() called with: " + "");
    }<br>    //当Fragment被滑到不可见的位置,offScreen时,调用
    protected void onFragmentStopLazy() {
        Log.d("TAG", "onFragmentStopLazy() called with: " + "");
    }<br>    protected void onCreateViewLazy(Bundle savedInstanceState) {
        Log.d("TAG", "onCreateViewLazy() called with: " + "savedInstanceState = [" + savedInstanceState + "]");
    }<br>    protected void onResumeLazy() {
        Log.d("TAG", "onResumeLazy() called with: " + "");
    }<br>    protected void onPauseLazy() {
        Log.d("TAG", "onPauseLazy() called with: " + "");
    }<br>    protected void onDestroyViewLazy() {<br>    }<br>    @Override
    @Deprecated
    public final void onResume() {
        Log.d("TAG", "onResume() : " + "getUserVisibleHint():" + getUserVisibleHint());
        super.onResume();
        if (isInit) {
            onResumeLazy();
        }
    }<br>    @Override
    @Deprecated
    public final void onPause() {
        Log.d("TAG", "onPause() : " + "getUserVisibleHint():" + getUserVisibleHint());
        super.onPause();
        if (isInit) {
            onPauseLazy();
        }
    }<br>    @Override
    @Deprecated
    public final void onDestroyView() {
        Log.d("TAG", "onDestroyView() : " + "getUserVisibleHint():" + getUserVisibleHint());
        super.onDestroyView();
        if (isInit) {
            onDestroyViewLazy();
        }
        isInit = false;
    }
}</code>
  • BaseFragment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<code>public class BaseFragment extends Fragment {
    protected LayoutInflater inflater;
    private View contentView;
    private Context context;
    private ViewGroup container;<br>    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getActivity().getApplicationContext();
    }<br>    //子类通过重写onCreateView,调用setOnContentView进行布局设置,否则contentView==null,返回null
    @Override
    public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        this.inflater = inflater;
        this.container = container;
        onCreateView(savedInstanceState);
        if (contentView == null)
            return super.onCreateView(inflater, container, savedInstanceState);
        return contentView;
    }<br>    protected void onCreateView(Bundle savedInstanceState) {<br>    }<br>    @Override
    public void onDestroyView() {
        super.onDestroyView();
        contentView = null;
        container = null;
        inflater = null;
    }<br>    public Context getApplicationContext() {
        return context;
    }<br>    public void setContentView(int layoutResID) {
        setContentView((ViewGroup) inflater.inflate(layoutResID, container, false));
    }<br>    public void setContentView(View view) {
        contentView = view;
    }<br>    public View getContentView() {
        return contentView;
    }<br>    public View findViewById(int id) {
        if (contentView != null)
            return contentView.findViewById(id);
        return null;
    }<br>    // http://stackoverflow.com/questions/15207305/getting-the-error-java-lang-illegalstateexception-activity-has-been-destroyed
    @Override
    public void onDetach() {
        Log.d("TAG", "onDetach() : ");
        super.onDetach();
        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);<br>        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }<br>    @Override
    public void onDestroy() {
        Log.d("TAG", "onDestroy() : ");
        super.onDestroy();
    }
}</code>

 

 

来自:http://www.jianshu.com/p/8a772b9df6d5

 





本文链接:https://it72.com:4443/11112.htm

推荐阅读
最新回复 (0)
返回