Tablayout+Viewpager+Fragment组合使用以及懒加载机制
下面这个界面在日常开发中简直太常见不过了,viewpager+fragment组合出来的效果!
首先介绍一下使用方法:
xml文件
属性说明:android:background="#EF8D11"
背景色app:tabIndicatorColor="#EF4A11"
tab文字下方的那条线的颜色app:tabMode="scrollable"
如果tab过多超出屏幕宽度可以水平滚动app:tabSelectedTextColor="#FFFFFF"
tab被选中的时候文字的颜色app:tabTextColor="#FFFFFF"
tab未被选中时文字的颜色app:tabTextAppearance="@style/MyTabLayoutTextAppearance"
自定义字体大小(一般使用默认即可)
123 | <style name="MyTabLayoutTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"> <item name="android:textSize">12spitem>style> |
java 代码
private void initView(View view) { mTablayout = (TabLayout) view.findViewById(R.id.tab_layout); //mTablayout.setTabMode(TabLayout.MODE_SCROLLABLE);//挤在一起显示 viewpager = (ViewPager) view.findViewById(R.id.viewpager); setupViewPager(viewpager); mTablayout.addTab(mTablayout.newTab().setText("头条")); mTablayout.addTab(mTablayout.newTab().setText("NBA")); mTablayout.addTab(mTablayout.newTab().setText("汽车")); mTablayout.addTab(mTablayout.newTab().setText("笑话")); mTablayout.setupWithViewPager(viewpager); } private void setupViewPager(ViewPager viewpager) { MyPagerAdapter adapter=new MyPagerAdapter(getChildFragmentManager()); adapter.addFragment(FirstListFragment.newInstance(ONE),"头条"); adapter.addFragment(FirstListFragment.newInstance(TWO),"NBA"); adapter.addFragment(FirstListFragment.newInstance(THREE),"汽车"); adapter.addFragment(FirstListFragment.newInstance(FOUR),"笑话"); viewpager.setAdapter(adapter); }
MyPagerAdaper public static class MyPagerAdapter extends FragmentPagerAdapter{ private final List mFragment=new ArrayList(); private final List mFragmentTitle=new ArrayList(); public void addFragment(Fragment fragment,String title){ mFragment.add(fragment); mFragmentTitle.add(title); } public MyPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return mFragment.get(position); } @Override public int getCount() { return mFragment.size(); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitle.get(position); } }
懒加载定义
Fragment的UI界面对用户可见的时候才加载数据。
怎么判断什么是否对用户可见呢?
public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (getUserVisibleHint()) { //可见 } else { //不可见 } }
注意:fragment的缓加载,优先于oncreate方法执行,且每次切换fragment都会执行此方法!
代码
为了方便,封装一个基类 LazyLoadFragment,提供一个 loadData() 方法供调用去加载数据
public abstract class LazyLoadFragment extends Fragment { /** * 控件是否初始化完成 */ private boolean isViewCreated; /** * 数据是否已加载完毕 */ private boolean isLoadDataCompleted; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(getLayout(), container, false); initViews(view); isViewCreated = true; return view; } public abstract int getLayout(); public abstract void initViews(View view); @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser && isViewCreated && !isLoadDataCompleted) { isLoadDataCompleted = true; loadData(); } } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (getUserVisibleHint()) { isLoadDataCompleted = true; loadData(); } } /** * 子类实现加载数据的方法 */ public abstract void loadData();
注: 为什么 loadData()
会在两个地方执行?在 setUserVisibleHint 方法里执行我还能理解,为什么 onActivityCreated 也要执行呢?
因为,ViewPager 默认显示第一页,第一页肯定要先加载数据,而且 setUserVisibleHint 的执行顺序又是在 onCreatView 之前,同时 onCreatView 需要初始化界面和修改 isViewCreated 的值。所以就需要在 onActivityCreated 里执行一次。
上面图片项目源码:点击打开链接
更多相关文章
- android Run模式也会出现"Waiting for debugger"的解决方法
- Android(安卓)studio 常用快捷键记录
- Android(安卓)提醒用户输入错误的方法
- Android的常见控件(TextView、EditText、Button、Menu)使用
- Binder实现分析
- Android绘画之扭曲图像
- Android四种加载方式
- Android打电话过程
- Android---把数据保存到数据库中(一)