ViewPager+Fragment取消预加载(延迟加载)(转)

原文:http://www.2cto.com/kf/201501/368954.html

在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方。例如你在ViewPager中添加了三个Fragment,当加载ViewPager中第一个Fragment时,它会默认帮你预先加载了第二个Fragment,当你加载第二个Fragment时,它会帮你加载第三个Fragment。这样虽然有时很好,但是用户只需看一个Fragment时,我们就做了一些多余工作加载了第二个Fragment。在这只需要取消Fragment的预加载即可,只有当用户切换到某个Fragment才加载..

首先,介绍两个方法void setUserVisibleHint(boolean isVisibleToUser)、boolean getUserVisibleHint(),它们分别用作设置/获得Fragment可见状态,我们可以重写Fragment在其中做判断,代码如下:

?


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

import android.support.v4.app.Fragment;

public abstract class BaseFragment extends Fragment {

    

    /** Fragment当前状态是否可见 */

    protected boolean isVisible;

    

    

    @Override

    public void setUserVisibleHint(boolean isVisibleToUser) {

        super.setUserVisibleHint(isVisibleToUser);

        

        if(getUserVisibleHint()) {

            isVisible = true;

            onVisible();

        } else {

            isVisible = false;

            onInvisible();

        }

    }

    

    

    /**

     * 可见

     */

    protected void onVisible() {

        lazyLoad();    

    }

    

    

    /**

     * 不可见

     */

    protected void onInvisible() {

        

        

    }

    

    

    /**

     * 延迟加载

     * 子类必须重写此方法

     */

    protected abstract void lazyLoad();

}

在我们的Fragment中,只需要继承这个类,然后重写其中的lazyLoad()方法,当Fragment对用户可见(即用户切换到此Fragment时)我们在lazyLoad()中加载所需数据,详细代码看下面,我写了个假的获取数据线程:

?


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

import android.os.AsyncTask;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.TextView;

public class CustomListFragment extends BaseFragment {

    private static final String FRAGMENT_INDEX = fragment_index;

    private final int FIRST_FRAGMENT = 0;

    private final int SECOND_FRAGMENT = 1;

    private final int THIRD_FRAGMENT = 2;

    private TextView mFragmentView;

    private int mCurIndex = -1;

    /** 标志位,标志已经初始化完成 */

    private boolean isPrepared;

    /** 是否已被加载过一次,第二次就不再去请求数据了 */

    private boolean mHasLoadedOnce;

    /**

     * 创建新实例

     *

     * @param index

     * @return

     */

    public static CustomListFragment newInstance(int index) {

        Bundle bundle = new Bundle();

        bundle.putInt(FRAGMENT_INDEX, index);

        CustomListFragment fragment = new CustomListFragment();

        fragment.setArguments(bundle);

        return fragment;

    }

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        if(mFragmentView == null) {

            mFragmentView = (TextView) inflater.inflate(R.layout.fragment, container, false);

            //获得索引值

            Bundle bundle = getArguments();

            if (bundle != null) {

                mCurIndex = bundle.getInt(FRAGMENT_INDEX);

            }

            isPrepared = true;

            lazyLoad();

        }

        

        //因为共用一个Fragment视图,所以当前这个视图已被加载到Activity中,必须先清除后再加入Activity

        ViewGroup parent = (ViewGroup)mFragmentView.getParent();

        if(parent != null) {

            parent.removeView(mFragmentView);

        }

        return mFragmentView;

    }

    @Override

    protected void lazyLoad() {

        if (!isPrepared || !isVisible || mHasLoadedOnce) {

            return;

        }

        new AsyncTask<void, boolean="">() {

            @Override

            protected void onPreExecute() {

                super.onPreExecute();

                //显示加载进度对话框

                UIHelper.showDialogForLoading(getActivity(), 正在加载..., true);

            }

            @Override

            protected Boolean doInBackground(Void... params) {

                try {

                    Thread.sleep(2000);

                    //在这里添加调用接口获取数据的代码

                    //doSomething()

                } catch (Exception e) {

                    e.printStackTrace();

                }

                return true;

            }

            @Override

            protected void onPostExecute(Boolean isSuccess) {

                if (isSuccess) {

                    // 加载成功

                    setView();

                    mHasLoadedOnce = true;

                } else {

                    // 加载失败

                }

                //关闭对话框

                UIHelper.hideDialogForLoading();

            }

        }.execute();

    }

    private void setView() {

        // 根据索引加载不同视图

        switch (mCurIndex) {

        case FIRST_FRAGMENT:

            mFragmentView.setText(第一个);

            break;

        case SECOND_FRAGMENT:

            mFragmentView.setText(第二个);

            break;

        case THIRD_FRAGMENT:

            mFragmentView.setText(第三个);

            break;

        }

    }

}</void,>

到这里我们只是写好了Fragment,在FragmentActivity中还需要对ViewPager设置一下,让它每次只加载一个Fragment,ViewPager.setOffscreenPageLimit(int limit),其中参数可以设为0或者1,参数小于1时,会默认用1来作为参数,未设置之前,ViewPager会默认加载两个Fragment。所以,我们只需要调用下它,设置下加载Fragment个数即可。

?


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

import java.util.ArrayList;

import java.util.List;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentActivity;

import android.support.v4.view.ViewPager;

import android.support.v4.view.ViewPager.OnPageChangeListener;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.RadioButton;

import android.os.Bundle;

public class MainActivity extends FragmentActivity implements OnClickListener{

    private RadioButton mFstBtn;

    private RadioButton mSndBtn;

    private RadioButton mThdBtn;

    

    private ViewPager mViewPager;

    private ListFragmentPagerAdapter mPagerAdapter;

    private List<fragment> mFragments = new ArrayList<fragment>();

    

    private final int FIRST_FRAGMENT = 0;

    private final int SECOND_FRAGMENT = 1;

    private final int THIRD_FRAGMENT = 2;

    

    

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        initButton();

        initViewPager();

    }

    

    

    /**

     * 初始化按钮

     */

    private void initButton() {

        mFstBtn = (RadioButton)findViewById(R.id.id_rb_fst);

        mFstBtn.setOnClickListener(this);

        mSndBtn = (RadioButton)findViewById(R.id.id_rb_snd);

        mSndBtn.setOnClickListener(this);

        mThdBtn = (RadioButton)findViewById(R.id.id_rb_thd);

        mThdBtn.setOnClickListener(this);

    }

    

    

    /**

     * 初始化ViewPager控件

     */

    private void initViewPager() {

        mViewPager = (ViewPager)findViewById(R.id.id_vp_viewpager);

        //关闭预加载,默认一次只加载一个Fragment

        mViewPager.setOffscreenPageLimit(1);

        //添加Fragment

        mFragments.add(CustomListFragment.newInstance(FIRST_FRAGMENT));

        mFragments.add(CustomListFragment.newInstance(SECOND_FRAGMENT));

        mFragments.add(CustomListFragment.newInstance(THIRD_FRAGMENT));

        //适配器

        mPagerAdapter = new ListFragmentPagerAdapter(getSupportFragmentManager(), mFragments);

        mViewPager.setAdapter(mPagerAdapter);

        mViewPager.setOnPageChangeListener(onPageChangeListener);

    }

    

    private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {

        

        @Override

        public void onPageSelected(int position) {

            //根据用户选中的按钮修改按钮样式

            switch (position) {

            case FIRST_FRAGMENT:

                mFstBtn.setChecked(true);

                mSndBtn.setChecked(false);

                mThdBtn.setChecked(false);

                break;

            case SECOND_FRAGMENT:

                mFstBtn.setChecked(false);

                mSndBtn.setChecked(true);

                mThdBtn.setChecked(false);

                break;

                

            case THIRD_FRAGMENT:

                mFstBtn.setChecked(false);

                mSndBtn.setChecked(false);

                mThdBtn.setChecked(true);

            break;

            }

        }

        

        @Override

        public void onPageScrolled(int arg0, float arg1, int arg2) {}

        

        @Override

        public void onPageScrollStateChanged(int arg0) {}

    };

    

    

    @Override

    public void onClick(View v) {

        switch (v.getId()) {

        case R.id.id_rb_fst:

            mViewPager.setCurrentItem(FIRST_FRAGMENT);

            break;

        case R.id.id_rb_snd:

            mViewPager.setCurrentItem(SECOND_FRAGMENT);

            break;

            

        case R.id.id_rb_thd:

            mViewPager.setCurrentItem(THIRD_FRAGMENT);

            break;

        }

    }

}

</fragment></fragment>

时间: 2024-11-09 07:36:13

ViewPager+Fragment取消预加载(延迟加载)(转)的相关文章

ViewPager+Fragment取消预加载(延迟加载)

在项目中,都或多或少地使用的Tab布局,所以大都会用到ViewPager+Fragment,但是Fragment有个不好或者太好的地方.例如你在ViewPager中添加了三个Fragment,当加载ViewPager中第一个Fragment时,它会默认帮你预先加载了第二个Fragment,当你加载第二个Fragment时,它会帮你加载第三个Fragment.这样虽然有时很好,但是用户只需看一个Fragment时,我们就做了一些多余工作加载了第二个Fragment.在这只需要取消Fragment的

Android viewpager + fragment取消预加载

1,在fragment中重写setUserVisibleHint方法private boolean isVisibleToUser;@Overridepublic void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); this.isVisibleToUser = isVisibleToUser; if (isVisibleToUser) { // TODO:1,如

高仿微信主界面:ViewPage+Fragment 不预加载Fragment 也不会销毁Fragment

微信支持下面四个Tab滑动,之前做的demo,遇到两个问题,1:Fragment会预加载,2:创建过的Fragment,来回滑动,会销毁重新创建.今天我这个demo,就要解决这两个问题.第一个问题需要导入一个新的V4包,最后我会提供,ViewPage要设置 mViewPager .setOffscreenPageLimit(0);这样的就能解决预加载的问题.第二个问题:我贴上代码: package com.example.fragmentviewpage; import java.util.Ar

Android ViewPager Fragment使用懒加载提升性能

?? Android ViewPager Fragment使用懒加载提升性能 Fragment在如今的Android开发中越来越普遍,但是当ViewPager结合Fragment时候,由于Android ViewPager内在的加载机制,导致一个比较严重的加载性能问题,具体来说,假设一个ViewPager中有n多个Fragment,那么ViewPager在初始化阶段将一次性的初始化FragmentPagerAdapter中的至少3个Fragment(如果Fragment多于3),创建和加载Fra

(ViewPager+Fragment)动态加载、删除页面,Fragmen中嵌套使用ViewPager

1.(ViewPager+Fragment)动态加载.删除页面 a.首先adapter要继承FragmentStatePagerAdapter. b.在PagerAdatpar重写getItemPosition(),return POSITION_NONE 即可每次刷新加载图面. 2.Fragmen中嵌套使用ViewPager 和activity中一样使用,将传入的getSupportFragmentManager替换成getChildFragmentManager即可.

android Viewpager取消预加载及Fragment方法的学习

1.在使用ViewPager嵌套Fragment的时候,由于VIewPager的几个Adapter的设置来说,都会有一定的预加载.通过设置setOffscreenPageLimit(int number) 来设置预加载的熟练,在V4包中,默认的预加载是1,即使你设置为0,也是不起作用的,设置的只能是大于1才会有效果的.我们需要通过更改V4包中的默认属性才可以. 更改过的V4 包下载地址: 2.限制预加载,会出现滑动过程中卡顿现象.其实Fragment中防止预加载主要是防止数据的预加载,Fragm

viewpager+fragment的懒加载实现微信点击和滑动切换功能(切换效果)

前言 1.从上一片文章之后已经半年没有写文章了,那篇文章之后公司进入疯狂的加班,一直到放年假.年后回来之后换了一家创业公司之后,然后又进入疯狂的加班(≧﹏ ≦) -所以一直都没有写文章(其实这都是借口⊙﹏⊙).现在公司没有那么忙了,也该把文章捡起来了,这毕竟是百利有一害的事(一害:费时间). 2.这半年里除了对代码的热情更加高涨(虽然它总是虐我千百遍(≧﹏ ≦) ),还深深的中了爬山的毒,对于年轻的我来说,爬山让我明白了许多.懂得了许多,也锻炼了我的身体.对于程序员来说身体是非常重要的,大家在周

Android之Viewpager+Fragment实现懒加载

我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用.而ViewPager默认会缓存三页数据,即:Viewpager每加载一个Fragment,都会预先加载此Fragment左侧或右侧的Fragment.而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源,浪费用户流量不止,还造成卡顿,这样的结果,我们当然不会满意.那么,能不能做到当切换到这个fr

js预加载/延迟加载

Pre loader 预加载一般有两种常用方式:xhr和动态插入节点的方式.动态插入节点是最为简单也最为广泛的一种异步加载方式,然后使用动态插入节点方法加载的文件都会 在加载后立即执行,javascript的执行一方面会占用浏览器js执行进程,另一方面也可能改变页面结构,而css 的执行更有可能让整个页面变化.xhr方式虽然不会执行脚本,但是由于同域的限制 Lazy loader方式在一些图片非常多的网站中非常有用,在浏览器可视区域外的图片不会被载入,直到用户将页面滚动到它们所在的位置才加载,这