Tablayout+Viewpager+Fragment组合使用以及懒加载机制

下面这个界面在日常开发中简直太常见不过了,viewpager+fragment组合出来的效果!

                              

首先介绍一下使用方法:

xml文件

[java]  view plain  copy
  1.        android:id="@+id/tab_layout"  
  2.        android:layout_width="match_parent"  
  3.        android:layout_height="wrap_content"  
  4.        android:background="#EF8D11"  
  5.        app:tabIndicatorColor="#EF4A11"  
  6.        app:tabMode="scrollable"  
  7.        app:tabSelectedTextColor="#FFFFFF"  
  8.        app:tabTextAppearance="@style/MyTabLayoutTextAppearance"  
  9.        app:tabTextColor="#FFFFFF" />  
  10.    
  11.        android:id="@+id/view_pager"  
  12.        android:layout_width="match_parent"  
  13.        android:layout_height="match_parent" />  

属性说明:
android:background="#EF8D11" 背景色
app:tabIndicatorColor="#EF4A11" tab文字下方的那条线的颜色
app:tabMode="scrollable" 如果tab过多超出屏幕宽度可以水平滚动
app:tabSelectedTextColor="#FFFFFF" tab被选中的时候文字的颜色
app:tabTextColor="#FFFFFF" tab未被选中时文字的颜色
app:tabTextAppearance="@style/MyTabLayoutTextAppearance" 自定义字体大小(一般使用默认即可)

1
2
3
<style name="MyTabLayoutTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse">
    <item name="android:textSize">12spitem>
style>

java 代码

[java]  view plain  copy
  1. private void initView(View view) {  
  2.   
  3.     mTablayout = (TabLayout) view.findViewById(R.id.tab_layout);  
  4.     //mTablayout.setTabMode(TabLayout.MODE_SCROLLABLE);//挤在一起显示  
  5.     viewpager = (ViewPager) view.findViewById(R.id.viewpager);  
  6.     setupViewPager(viewpager);  
  7.     mTablayout.addTab(mTablayout.newTab().setText("头条"));  
  8.     mTablayout.addTab(mTablayout.newTab().setText("NBA"));  
  9.     mTablayout.addTab(mTablayout.newTab().setText("汽车"));  
  10.     mTablayout.addTab(mTablayout.newTab().setText("笑话"));  
  11.   
  12.     mTablayout.setupWithViewPager(viewpager);  
  13.   
  14. }  
  15.   
  16. private void setupViewPager(ViewPager viewpager) {  
  17.     MyPagerAdapter adapter=new MyPagerAdapter(getChildFragmentManager());  
  18.     adapter.addFragment(FirstListFragment.newInstance(ONE),"头条");  
  19.     adapter.addFragment(FirstListFragment.newInstance(TWO),"NBA");  
  20.     adapter.addFragment(FirstListFragment.newInstance(THREE),"汽车");  
  21.     adapter.addFragment(FirstListFragment.newInstance(FOUR),"笑话");  
  22.     viewpager.setAdapter(adapter);  
  23. }  
MyPagerAdaper

[java]  view plain  copy
  1. public  static class MyPagerAdapter extends FragmentPagerAdapter{  
  2.        private final List mFragment=new ArrayList();  
  3.        private final List mFragmentTitle=new ArrayList();  
  4.   
  5.        public void addFragment(Fragment  fragment,String title){  
  6.            mFragment.add(fragment);  
  7.            mFragmentTitle.add(title);  
  8.        }  
  9.        public MyPagerAdapter(FragmentManager fm) {  
  10.            super(fm);  
  11.        }  
  12.   
  13.        @Override  
  14.        public Fragment getItem(int position) {  
  15.            return mFragment.get(position);  
  16.        }  
  17.   
  18.        @Override  
  19.        public int getCount() {  
  20.            return mFragment.size();  
  21.   
  22.        }  
  23.        @Override  
  24.        public CharSequence getPageTitle(int position) {  
  25.            return mFragmentTitle.get(position);  
  26.        }  
  27.    }  

懒加载定义

Fragment的UI界面对用户可见的时候才加载数据。

怎么判断什么是否对用户可见呢?

[java]  view plain  copy
  1. public void setUserVisibleHint(boolean isVisibleToUser) {  
  2.         super.setUserVisibleHint(isVisibleToUser);  
  3.         if (getUserVisibleHint()) {  
  4.             //可见  
  5.         } else {  
  6.             //不可见  
  7.         }  
  8.     }  

注意:fragment的缓加载,优先于oncreate方法执行,且每次切换fragment都会执行此方法!

代码

为了方便,封装一个基类 LazyLoadFragment,提供一个 loadData() 方法供调用去加载数据

[java]  view plain  copy
  1. public abstract class LazyLoadFragment extends Fragment {  
  2.   
  3.     /** 
  4.      * 控件是否初始化完成 
  5.      */  
  6.     private boolean isViewCreated;  
  7.     /** 
  8.      * 数据是否已加载完毕 
  9.      */  
  10.     private boolean isLoadDataCompleted;  
  11.   
  12.     @Nullable  
  13.     @Override  
  14.     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {  
  15.         View view = inflater.inflate(getLayout(), container, false);  
  16.         initViews(view);  
  17.         isViewCreated = true;  
  18.         return view;  
  19.     }  
  20.   
  21.     public abstract int getLayout();  
  22.     public abstract void initViews(View view);  
  23.   
  24.     @Override  
  25.     public void setUserVisibleHint(boolean isVisibleToUser) {  
  26.         super.setUserVisibleHint(isVisibleToUser);  
  27.         if (isVisibleToUser && isViewCreated && !isLoadDataCompleted) {  
  28.             isLoadDataCompleted = true;  
  29.             loadData();  
  30.         }  
  31.     }  
  32.   
  33.     @Override  
  34.     public void onActivityCreated(@Nullable Bundle savedInstanceState) {  
  35.         super.onActivityCreated(savedInstanceState);  
  36.   
  37.         if (getUserVisibleHint()) {  
  38.             isLoadDataCompleted = true;  
  39.             loadData();  
  40.         }  
  41.     }  
  42.   
  43.     /** 
  44.      * 子类实现加载数据的方法 
  45.      */  
  46.     public abstract  void loadData();  
注:

      为什么 loadData() 会在两个地方执行?在 setUserVisibleHint 方法里执行我还能理解,为什么 onActivityCreated 也要执行呢?

        因为,ViewPager 默认显示第一页,第一页肯定要先加载数据,而且 setUserVisibleHint 的执行顺序又是在 onCreatView 之前,同时 onCreatView 需要初始化界面和修改 isViewCreated 的值。所以就需要在 onActivityCreated 里执行一次。

你可能感兴趣的:(Tablayout+Viewpager+Fragment组合使用以及懒加载机制)