├── 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 |