关于TabLayout+ViewPager组合实现多页面滑动
2015-06-26 11:05
253 查看
转载请注明出处:/article/8284642.html
在android提供的design library中新增了一个控件,叫TabLayout,它继承自HorizontalScrollView,可以实现android中多页面滑动切换效果。但是一般需要和ViewPager组合使用,官方API地址:https://developer.android.com/reference/android/support/design/widget/TabLayout.html
下面来讲解一下具体的使用流程:
首先,要使用该控件就需要添加design library,在android studio(还没有使用Android studio的小伙伴们要赶紧更换啦)中添加依赖
compile ‘com.android.support:design:22.2.0’
然后再布局文件中使用TabLayout
紧接着在下面添加ViewPager
布局文件完成了,接下来去定义ViewPager中的适配器,这里我使用的是Fragment,所以继承自FragmentPagerAdapter ,代码如下:
适配器中需要两个数据集合,分配填充Fragment和显示的标题。
然后在需要使用的页面添加如下代码:
现在适配器和数据已经准备好了,那么接下来就是要把数据放入ViewPager中,并使ViewPager和TabLayout相关联:
关联之后运行发现,其实ViewPager由于预加载机制,导致每次都会提前加载下一个页面,如果页面的数据量大,那么这将会占用大量的内存,有什么办法可以只加载当前显示的页面呢?
通过查找相关资料发现,有一个方法setOffscreenPageLimit(int),该方法的作用是设置提前加载页面的数量,尝试使用
继续查阅资料后发现,原来这是由于ViewPager的机制导致的,最少需要预加载一个页面,Requested offscreen page limit 0 too small; defaulting to 1,相关问题链接:http://stackoverflow.com/questions/10073214/viewpager-setoffscreenpagelimit0-doesnt-work-as-expected
发现了可以完美解决该问题的方法:
在Fragment中有一个方法,setUserVisibleHint,该方法可以获取当前页面的展示情况
基本到这一步功能已经实现了,但是,还有一些细节需要注意,到底ViewPager滑动的时候为什么会造成TabLayout的标题也随之更换呢?原来setupWithViewPager被调用的时候,执行了下面的代码
到最后,还有一个问题,那么就是如果我们的标题有多条,导致超出了TabLayout的显示范围,这该如何解决呢?很简单,查阅官方API发现,TabLayout有一个方法是setTabMode,它是用来设置TabLayout的展示模式,而这个方法接受两个常量,MODE_SCROLLABLE 以及 MODE_FIXED,显而易见,当我们设置为MODE_SCROLLABLE 它就能自动根据标题的数量,滑动展示啦,功能到这里就完美实现了!
在android提供的design library中新增了一个控件,叫TabLayout,它继承自HorizontalScrollView,可以实现android中多页面滑动切换效果。但是一般需要和ViewPager组合使用,官方API地址:https://developer.android.com/reference/android/support/design/widget/TabLayout.html
下面来讲解一下具体的使用流程:
首先,要使用该控件就需要添加design library,在android studio(还没有使用Android studio的小伙伴们要赶紧更换啦)中添加依赖
compile ‘com.android.support:design:22.2.0’
然后再布局文件中使用TabLayout
<android.support.design.widget.TabLayout android:id="@+id/tablayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" />
紧接着在下面添加ViewPager
<android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/tablayout" />
布局文件完成了,接下来去定义ViewPager中的适配器,这里我使用的是Fragment,所以继承自FragmentPagerAdapter ,代码如下:
public class MyPageAdapter extends FragmentPagerAdapter { ArrayList<Fragment> datas; ArrayList<String> titles; public CommunityPageAdapter(FragmentManager fm) { super(fm); } public void setData(ArrayList<Fragment> datas) { this.datas = datas; } public void setTitles(ArrayList<String> titles) { this.titles = titles; } @Override public Fragment getItem(int position) { return datas == null ? null : datas.get(position); } @Override public int getCount() { return datas == null ? 0 : datas.size(); } @Override public CharSequence getPageTitle(int position) { return titles == null ? null : titles.get(position); } }
适配器中需要两个数据集合,分配填充Fragment和显示的标题。
然后在需要使用的页面添加如下代码:
MyPageAdapter myPageAdapter = new MyPageAdapter(getFragmentManager()); ArrayList<Fragment> datas = new ArrayList<Fragment>(); datas.add(new AFragment()); datas.add(new BFragment()); datas.add(new CFragment()); myPageAdapter.setData(datas); ArrayList<String> titles = new ArrayList<String>(); titles.add("A"); titles.add("B"); titles.add("C"); myPageAdapter.setTitles(titles);
现在适配器和数据已经准备好了,那么接下来就是要把数据放入ViewPager中,并使ViewPager和TabLayout相关联:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tablayout); ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager); // 将适配器设置进ViewPager viewPager.setAdapter(myPageAdapter); // 将ViewPager与TabLayout相关联 tabLayout.setupWithViewPager(viewPager);
关联之后运行发现,其实ViewPager由于预加载机制,导致每次都会提前加载下一个页面,如果页面的数据量大,那么这将会占用大量的内存,有什么办法可以只加载当前显示的页面呢?
通过查找相关资料发现,有一个方法setOffscreenPageLimit(int),该方法的作用是设置提前加载页面的数量,尝试使用
viewPager.setOffscreenPageLimit(0);后发现无效。
继续查阅资料后发现,原来这是由于ViewPager的机制导致的,最少需要预加载一个页面,Requested offscreen page limit 0 too small; defaulting to 1,相关问题链接:http://stackoverflow.com/questions/10073214/viewpager-setoffscreenpagelimit0-doesnt-work-as-expected
发现了可以完美解决该问题的方法:
在Fragment中有一个方法,setUserVisibleHint,该方法可以获取当前页面的展示情况
@Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { // 页面正在展示,在这里加载你的数据 }else{ // 页面没有展示 } }
基本到这一步功能已经实现了,但是,还有一些细节需要注意,到底ViewPager滑动的时候为什么会造成TabLayout的标题也随之更换呢?原来setupWithViewPager被调用的时候,执行了下面的代码
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this)); this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
到最后,还有一个问题,那么就是如果我们的标题有多条,导致超出了TabLayout的显示范围,这该如何解决呢?很简单,查阅官方API发现,TabLayout有一个方法是setTabMode,它是用来设置TabLayout的展示模式,而这个方法接受两个常量,MODE_SCROLLABLE 以及 MODE_FIXED,显而易见,当我们设置为MODE_SCROLLABLE 它就能自动根据标题的数量,滑动展示啦,功能到这里就完美实现了!
相关文章推荐
- Fibonacci Again
- tcprstat工具安装与使用
- 【IE bug 解决办法】IE下(IE10及以下)当元素为absolute定位时,点击事件失效的解决办法
- hibernate根据映射文件生成数据库对象
- linux防僵尸进程的学习总结
- 绩效沟通-BEST原则
- Android开发框架androidannotations的使用
- socket选项设置
- jdbc/ojdbc连oracle的三种方式(转)
- 【IE bug 解决办法】IE下(IE10及以下)当元素为absolute定位时,点击事件失效的解决办法 分类: ie ie bug ie absolute click 2015-06-26 11:05 21人阅读 评论(0) 收藏
- Fibonacci Again 分类: HDU 2015-06-26 11:05 13人阅读 评论(0) 收藏
- bash: ./make_ext4fs: No such file or directory 错误解决方法
- 以文件形式缓存php变量的方法
- 使用keychain保存用户名和密码等敏感信息 KeychainItemWrapper和SFHFKeychainUtils。
- SSH点餐系统出错问题如何解决
- 栈区和堆区内存分配区别
- UNIX环境高级编程学习笔记(七)系统数据文件和信息
- GridView动态设置Item的宽高 第一个Item不显示的问题
- 一个简单的js拖拽
- Spring 动态多数据源