上一篇:
Android自带的TabLayout实现滑动翻页效果(实例)
这一篇讲下一个三方控件FlycoTabLayout,gitHub地址,建议直接download下来,运行一下。里面包含三个控件CommonTabLayout、SegmentTabLayout、SlidingTabLayout。
引入
compile 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
复制代码
CommonTabLayout:
CommonTabLayout继承自FrameLayout,类似于一个RadioGroup,可以在xml布局中设置commonTabLayout的布局特性;另外也可以在代码中设置未读消息、消息数量。如果要和fragment绑定,实现fragment的切换需要手动通过fragmentManager来管理切换;viewPager也是同理;也可通过fragmentPagerAdapter实现fragment和viewPager的绑定;
private fun initData() {
for ( i in 0 until 4) {
mTabEntities.add(TabEntity(mTabTitle[i], mTabUnselectedIcons[i], mTabselectedIcons[i]))
}
commonTabLayout.setTabData(ArrayList(mTabEntities))
commonTabLayout.setOnTabSelectListener(object: OnTabSelectListener{
override fun onTabSelect(position: Int) {
Log.e("zhen", "onTabSelect: $position")
}
override fun onTabReselect(position: Int) {
Log.e("zhen", "onTabReselect: $position")
}
})
}
class TabEntity(val title: String, val unselectedIcon: Int,
val selectedIcon: Int) : CustomTabEntity {
override fun getTabUnselectedIcon(): Int {
return unselectedIcon
}
override fun getTabSelectedIcon(): Int {
return selectedIcon
}
override fun getTabTitle(): String {
return title
}
}
复制代码
SegmentTabLayout
SegmentTabLayout 通过setTabData可以和fragment绑定,内部实现的是和fragmentManager一样的功能;如果要绑定viewPager的话,需要手动写,就是我屏蔽掉的那一部分啦!
R.id.container就是容纳fragment的布局容器啦!
private fun initTab() {
mFragmentList.add(FragmentOne())
mFragmentList.add(FragmentTwo())
mFragmentList.add(FragmentThree())
segmentTabLayout.setTabData(mTabTitle, this, R.id.container, mFragmentList)
// mAdapter = FragmentPagerAdapterNew(supportFragmentManager, mFragmentList, mTabTitle.toList())
// viewPager.adapter = mAdapter
//
// segmentTabLayout.setTabData(mTabTitle)
// segmentTabLayout.setOnTabSelectListener(object : OnTabSelectListener{
// override fun onTabSelect(position: Int) {
// Log.e("zhen", "segmentTabLayout onTabSelect $position")
// viewPager.currentItem = position
// }
//
// override fun onTabReselect(position: Int) {
// Log.e("zhen", "segmentTabLayout onTabReselect $position")
// }
// })
//
// viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener{
// override fun onPageScrollStateChanged(state: Int) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
// }
//
// override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
// }
//
// override fun onPageSelected(position: Int) {
// segmentTabLayout.currentTab = position
// }
//
// })
}
复制代码
SlidingTabLayout
SlidingTabLayout通过setViewPager实现了和viewPager的强绑定,内部也就是实现了fragmentPagerAdapter啦
private fun initTab() {
mFragmentList.add(FragmentOne())
mFragmentList.add(FragmentTwo())
mFragmentList.add(FragmentThree())
mFragmentList.add(FragmentOne())
slidingTabLayout.setViewPager(viewPager, mTabTitle, this, mFragmentList)
}
复制代码
PagerAdapter
ViewPager是一个可以实现左右滑动的控件,PagerAdapter 是ViewPager的适配器,给ViewPager设置了PagerAdapter就能正常工作啦。
我们需要重写PagerAdapter的四个方法,instantiateItem()、destroyItem()、isViewFromObject()、getCount()
viewPager是一个容器,里面包含了很多item,一次展示一个item,item需要提前通过instantiateItem()加载出来,所以这里做的工作主要是加载布局,设置内容; 当item变得不可见,且不需要缓存时,又会及时的从viewPager中通过destroyItem()移除;
PagerAdapter有两个子类FragmentPagerAdapter和FragmentStatePagerAdapter
如果我们通过FragmentPagerAdapter和FragmentStatePagerAdapter来实现的话,只需要重写getItem()、getCount(),因为内部已经实现了instantiateItem()和destroyItem()、isViewFromObject(),他们最大的区别就是:用户访问过的页面不可见之后是否会保留在内存中
FragmentPagerAdapter:
instantiateItem()和destroyItem()是通过fragmentManager的attach和detach实现的
FragmentPagerAdapter继承自PagerAdapter,主要用来展示多个Fragment页面,并且每一个Fragment都会被保存在fragment manager中。FragmentPagerAdapter最适用于那种少量且相对静态的页面,例如几个tab页。每一个用户访问过的fragment都会被保存在内存中,尽管他的视图层级可能会在不可见时被销毁。
FragmentStatePagerAdapter:
instantiateItem()和destroyItem()是通过fragmentManager的add和remove实现的,会及时的清理
FragmentStatePagerAdapter继承自PagerAdapter,主要使用Fragment来管理每个页面。这个类同样用来保存和恢复fragment页面的状态。FragmentStatePagerAdapter更多用于大量页面,例如视图列表。当某个页面对用户不再可见时,他们的整个fragment就会被销毁,仅保留fragment状态。相比于FragmentPagerAdapter,这样做的好处是在访问各个页面时能节约大量的内存开销,但代价是在页面切换时会增加非常多的开销。
PagerAdapter的使用:
adapter = PictureAdapter(activity!!, mData)
viewPager.adapter = adapter
复制代码
class PictureAdapter(val context: Context, val data: List<Int>): PagerAdapter() {
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view = LayoutInflater.from(context).inflate(R.layout.item_picture, null)
val picture = view.findViewById<ImageView>(R.id.picture)
picture.setImageResource(data[position])
container.addView(view)
return view
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View?)
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view == `object`
}
override fun getCount(): Int {
return data.size
}
}
复制代码