├── README.md
├── app
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── wangxw
│ │ └── fragmentlazyloaddemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── wangxw
│ │ │ └── fragmentlazyloaddemo
│ │ │ ├── MainActivity.java
│ │ │ ├── MainAdapter.java
│ │ │ └── fragment
│ │ │ ├── AFragment.java
│ │ │ ├── BFragment.java
│ │ │ ├── BaseFragment.java
│ │ │ └── CFragment.java
│ └── res
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ └── fragment_item.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── wangxw
│ └── fragmentlazyloaddemo
│ └── ExampleUnitTest.java
├── build.gradle
├── screenshots
├── fragment_lazyload.gif
└── viewpager_pre2pages.jpg
└── settings.gradle
/README.md:
--------------------------------------------------------------------------------
1 | # ViewPager+Fragment组合的预加载和懒加载
2 |
3 | [简书直达](http://www.jianshu.com/p/7a47907f49c2)
4 |
5 | [CSDN直达](http://blog.csdn.net/wangxw725/article/details/55001633)
6 |
7 | 预加载
8 |
9 |
10 |
11 | 懒加载
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "24.0.2"
6 | defaultConfig {
7 | applicationId "com.wangxw.fragmentlazyloaddemo"
8 | minSdkVersion 15
9 | targetSdkVersion 24
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:24.2.1'
28 | compile 'com.android.support:design:24.0.0'
29 | testCompile 'junit:junit:4.12'
30 | }
31 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Dev\Develop\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/wangxw/fragmentlazyloaddemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.wangxw.fragmentlazyloaddemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wangxw/fragmentlazyloaddemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo;
2 |
3 | import android.content.Intent;
4 | import android.support.design.widget.TabLayout;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v4.view.ViewPager;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | import com.wangxw.fragmentlazyloaddemo.fragment.AFragment;
15 | import com.wangxw.fragmentlazyloaddemo.fragment.BFragment;
16 | import com.wangxw.fragmentlazyloaddemo.fragment.CFragment;
17 |
18 | import java.util.ArrayList;
19 |
20 | public class MainActivity extends AppCompatActivity implements View.OnClickListener {
21 |
22 | private TabLayout mTabLayout;
23 | private ViewPager mViewPager;
24 | private LinearLayout mllLogs;
25 | private static int sOffScreenLimit = 1;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_main);
31 | initView();
32 | initData();
33 | initListener();
34 | }
35 |
36 | private void initView() {
37 | mTabLayout = (TabLayout) findViewById(R.id.tablayout);
38 | mViewPager = (ViewPager) findViewById(R.id.viewpager);
39 | mllLogs = (LinearLayout) findViewById(R.id.ll_log_container);
40 | }
41 |
42 | private void initData() {
43 | //填充数据
44 | ArrayList fragmentList = new ArrayList<>();
45 | fragmentList.add(new AFragment());
46 | fragmentList.add(new BFragment());
47 | fragmentList.add(new CFragment());
48 |
49 | ArrayList titleList = new ArrayList<>();
50 | for (int i = 0; i < 3; i++) {
51 | titleList.add("Page_"+i);
52 | }
53 |
54 | MainAdapter adapter = new MainAdapter(getSupportFragmentManager(), fragmentList, titleList);
55 | mViewPager.setAdapter(adapter);
56 | mTabLayout.setupWithViewPager(mViewPager);
57 | if(sOffScreenLimit >1){
58 | mViewPager.setOffscreenPageLimit(sOffScreenLimit);
59 | Log.i("wxw","偏移量>1...:"+ sOffScreenLimit);
60 | }else {
61 | Log.i("wxw","偏移量...:"+ sOffScreenLimit);
62 | }
63 | }
64 |
65 | private void initListener() {
66 | findViewById(R.id.btn_viewpager_mode_default).setOnClickListener(this);
67 | findViewById(R.id.btn_viewpager_mode_load2page).setOnClickListener(this);
68 | findViewById(R.id.btn_clear_log).setOnClickListener(this);
69 | }
70 |
71 | @Override
72 | public void onClick(View v) {
73 | switch (v.getId()){
74 | case R.id.btn_viewpager_mode_default: //默认模式
75 | sOffScreenLimit = 1;
76 | finish();
77 | startActivity(new Intent(this,MainActivity.class));
78 | overridePendingTransition(0,0);
79 | break;
80 | case R.id.btn_viewpager_mode_load2page: //预加载两页
81 | sOffScreenLimit = 2;
82 | finish();
83 | startActivity(new Intent(this,MainActivity.class));
84 | overridePendingTransition(0,0);
85 | break;
86 | case R.id.btn_clear_log: //清空Log
87 | mllLogs.removeAllViews();
88 | break;
89 | default:
90 | break;
91 | }
92 | }
93 |
94 | public void addLog(TextView logView){
95 | mllLogs.addView(logView);
96 | }
97 |
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wangxw/fragmentlazyloaddemo/MainAdapter.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by wangxw on 2017/2/10 0009 15:05.
11 | * E-mail:wangxw725@163.com
12 | * function:
13 | */
14 | public class MainAdapter extends FragmentPagerAdapter {
15 |
16 | List fragmentList;
17 | List titleList;
18 |
19 | public MainAdapter(FragmentManager fm, List fragmentList, List titleList) {
20 | super(fm);
21 | this.fragmentList = fragmentList;
22 | this.titleList = titleList;
23 | }
24 |
25 | @Override
26 | public int getCount() {
27 | return fragmentList!=null ? fragmentList.size() : 0;
28 | }
29 |
30 | @Override
31 | public Fragment getItem(int position) {
32 | return fragmentList.get(position);
33 | }
34 |
35 | @Override
36 | public CharSequence getPageTitle(int position) {
37 | return titleList.get(position);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wangxw/fragmentlazyloaddemo/fragment/AFragment.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import com.wangxw.fragmentlazyloaddemo.R;
13 |
14 | /**
15 | * Created by wangxw on 2017/2/10 0010 14:58.
16 | * E-mail:wangxw725@163.com
17 | * function:
18 | */
19 | public class AFragment extends BaseFragment {
20 |
21 | @Override
22 | protected void loadData() {
23 | Log.i("wxw","AFragment可见,可以加载数据了");
24 | }
25 |
26 | @Override
27 | protected String getFragmentTextviewContent() {
28 | return "Page_0";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wangxw/fragmentlazyloaddemo/fragment/BFragment.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import com.wangxw.fragmentlazyloaddemo.R;
13 |
14 | /**
15 | * Created by wangxw on 2017/2/10 0010 14:58.
16 | * E-mail:wangxw725@163.com
17 | * function:
18 | */
19 | public class BFragment extends BaseFragment {
20 |
21 |
22 | @Override
23 | protected void loadData() {
24 | Log.i("wxw","BFragment可见,可以加载数据了");
25 | }
26 |
27 | @Override
28 | protected String getFragmentTextviewContent() {
29 | return "Page_1";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wangxw/fragmentlazyloaddemo/fragment/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.TextView;
10 |
11 | import com.wangxw.fragmentlazyloaddemo.MainActivity;
12 | import com.wangxw.fragmentlazyloaddemo.R;
13 |
14 | /**
15 | * Created by wangxw on 2017/2/10 0010 15:21.
16 | * E-mail:wangxw725@163.com
17 | * function:
18 | */
19 | public abstract class BaseFragment extends Fragment {
20 |
21 | private String mTextviewContent;
22 | private MainActivity mMainActivity;
23 |
24 | //Fragment的View加载完毕的标记
25 | private boolean isViewCreated;
26 | //Fragment对用户可见的标记
27 | private boolean isUIVisible;
28 |
29 | @Override
30 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
31 | View view = inflater.inflate(R.layout.fragment_item, container, false);
32 | initView(view);
33 | return view ;
34 | }
35 |
36 | private void initView(View view) {
37 | TextView textView = (TextView) view.findViewById(R.id.textview);
38 | mTextviewContent = getFragmentTextviewContent();
39 | textView.setText(mTextviewContent);
40 |
41 | mMainActivity = (MainActivity) getActivity();
42 | printLog(mTextviewContent +"加载了");
43 | }
44 |
45 | @Override
46 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
47 | super.onViewCreated(view, savedInstanceState);
48 | isViewCreated = true;
49 | lazyLoad();
50 | }
51 |
52 | @Override
53 | public void setUserVisibleHint(boolean isVisibleToUser) {
54 | super.setUserVisibleHint(isVisibleToUser);
55 | //isVisibleToUser这个boolean值表示:该Fragment的UI 用户是否可见
56 | if (isVisibleToUser) {
57 | isUIVisible = true;
58 | lazyLoad();
59 | } else {
60 | isUIVisible = false;
61 | }
62 | }
63 |
64 | private void lazyLoad() {
65 | //这里进行双重标记判断,是因为setUserVisibleHint会多次回调,并且会在onCreateView执行前回调,必须确保onCreateView加载完毕且页面可见,才加载数据
66 | if (isViewCreated && isUIVisible) {
67 | loadData();
68 | //数据加载完毕,恢复标记,防止重复加载
69 | isViewCreated = false;
70 | isUIVisible = false;
71 |
72 | printLog(mTextviewContent+"可见,加载数据");
73 | }
74 | }
75 |
76 |
77 | protected abstract void loadData();
78 |
79 |
80 | @Override
81 | public void onDestroyView() {
82 | super.onDestroyView();
83 | //页面销毁,恢复标记
84 | isViewCreated = false;
85 | isUIVisible = false;
86 |
87 | printLog(mTextviewContent +"销毁了");
88 | }
89 |
90 | private void printLog(String logStr) {
91 | TextView logView = new TextView(getContext());
92 | logView.setText(logStr);
93 | mMainActivity.addLog(logView);
94 | }
95 |
96 | /**Fragment中TextView显示的内容*/
97 | protected abstract String getFragmentTextviewContent();
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/com/wangxw/fragmentlazyloaddemo/fragment/CFragment.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import com.wangxw.fragmentlazyloaddemo.R;
13 |
14 | /**
15 | * Created by wangxw on 2017/2/10 0010 14:58.
16 | * E-mail:wangxw725@163.com
17 | * function:
18 | */
19 | public class CFragment extends BaseFragment {
20 |
21 |
22 | @Override
23 | protected void loadData() {
24 | Log.i("wxw","CFragment可见,可以加载数据了");
25 | }
26 |
27 | @Override
28 | protected String getFragmentTextviewContent() {
29 | return "Page_2";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
22 |
23 |
24 |
28 |
29 |
30 |
35 |
36 |
41 |
42 |
43 |
44 |
45 |
50 |
51 |
56 |
57 |
62 |
63 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crocutax/FragmentLazyloadDemo/262492d5b12f473a231024d8b99f3c0c15018ecb/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crocutax/FragmentLazyloadDemo/262492d5b12f473a231024d8b99f3c0c15018ecb/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crocutax/FragmentLazyloadDemo/262492d5b12f473a231024d8b99f3c0c15018ecb/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crocutax/FragmentLazyloadDemo/262492d5b12f473a231024d8b99f3c0c15018ecb/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crocutax/FragmentLazyloadDemo/262492d5b12f473a231024d8b99f3c0c15018ecb/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FragmentLazyLoadDemo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/wangxw/fragmentlazyloaddemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.wangxw.fragmentlazyloaddemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/screenshots/fragment_lazyload.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crocutax/FragmentLazyloadDemo/262492d5b12f473a231024d8b99f3c0c15018ecb/screenshots/fragment_lazyload.gif
--------------------------------------------------------------------------------
/screenshots/viewpager_pre2pages.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crocutax/FragmentLazyloadDemo/262492d5b12f473a231024d8b99f3c0c15018ecb/screenshots/viewpager_pre2pages.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------