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