当前位置: 代码迷 >> 综合 >> TabLayout + ViewPager + Fragment 实现方式总结
  详细解决方案

TabLayout + ViewPager + Fragment 实现方式总结

热度:63   发布时间:2023-11-17 10:55:37.0

应用内加个Tab实现左右滑动,已经是司空见惯,也有很多大佬进行了各种封装,(纯粹是做一下记录证明周末没有躺尸)。

 

首先是Android原生的TabLayout和ViewPager。

可参考API  TabLayout 

 

实现方式1

TabLayout + ViewPager + Fragment 

1.两个Adapter的选用。

     (一)FragmentPagerAdapter 

 viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {@Overridepublic Fragment getItem(int position) {return fragments.get(position);}@Overridepublic int getCount() {return fragments.size();}@Nullable@Overridepublic CharSequence getPageTitle(int position) {return titles.get(position);}});tabLayout.setupWithViewPager(viewPager);

 

(二)FragmentStatePagerAdapter

 viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {@Overridepublic Fragment getItem(int position) {return fragments.get(position);}@Overridepublic int getCount() {return fragments.size();}@Nullable@Overridepublic CharSequence getPageTitle(int position) {return titles.get(position);}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {super.destroyItem(container, position, object);}});tabLayout.setupWithViewPager(viewPager);

 

总结:FragmentPagerAdapter内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的那种;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。(可以参考之前写的文章—— ViewPager刷新缓存问题 FragmentPagerAdapter+FragementStatePagerAdapter)

这只是一个简单的实现,更多的可以自己使用它的属性。

PS:延伸一个扩展功能,tab选中的时候字体变大。使用TabLayout去实现。直接上代码

 tabLayout.setOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {@Overridepublic void onTabSelected(TabLayout.Tab tab) {TextView title = (TextView)(((LinearLayout) ((LinearLayout) tabLayout.getChildAt(0)).getChildAt(tab.getPosition())).getChildAt(1));title.setTextColor(getResources().getColor(R.color.tab_selector));title.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));}@Overridepublic void onTabUnselected(TabLayout.Tab tab) {TextView title = (TextView)(((LinearLayout) ((LinearLayout) tabLayout.getChildAt(0)).getChildAt(tab.getPosition())).getChildAt(1));title.setTextColor(getResources().getColor(R.color.black));title.setTypeface(Typeface.DEFAULT);}@Overridepublic void onTabReselected(TabLayout.Tab tab) {}});

 

 

实现方式二

使用github上开源库,MagicIndicator  start(6598)  fork(1123),算的上是一个很厉害的开源项目。

具体使用请去查看README.md

MagicIndicator 可以实现的功能,即使Demo里面没有你想要的功能,你可以通过继承SimplePagerTitleView实现自己的效果,还有一个比较酷的点是指示器。

跟Tablayout相比   

使用上: 代码量都可以,如果加上自定义指示器和渐变效果完全可以碾压TabLayout

设计上:个人感觉模块划分很完美

效果:无论是直接用Demo还是自定义,遵守框架的设计都会很方便。

优点:指示器

上代码

        CommonNavigator commonNavigator = new CommonNavigator(this);commonNavigator.setAdjustMode(true);commonNavigator.setAdapter(new CommonNavigatorAdapter() {@Overridepublic int getCount() {return mDataList == null ? 0 : mDataList.size();}@Overridepublic IPagerTitleView getTitleView(Context context, final int index) {// 相当于TabSimplePagerTitleView simplePagerTitleView = new ScaleTransitionPagerTitleView(context);simplePagerTitleView.setText(mDataList.get(index));simplePagerTitleView.setTextSize(18);simplePagerTitleView.setNormalColor(Color.parseColor("#616161"));simplePagerTitleView.setSelectedColor(Color.parseColor("#f57c00"));simplePagerTitleView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mViewPager.setCurrentItem(index);}});return simplePagerTitleView;}@Overridepublic IPagerIndicator getIndicator(Context context) {// 指示器LinePagerIndicator indicator = new LinePagerIndicator(context);indicator.setStartInterpolator(new AccelerateInterpolator());indicator.setEndInterpolator(new DecelerateInterpolator(1.6f));indicator.setYOffset(UIUtil.dip2px(context, 39));indicator.setLineHeight(UIUtil.dip2px(context, 1));indicator.setColors(Color.parseColor("#f57c00"));return indicator;}});magicIndicator.setNavigator(commonNavigator);ViewPagerHelper.bind(magicIndicator, mViewPager);

具体细节就不扯太多,总之这个库很强大。

 

 

实现方式三

Github开源库  https://github.com/AndroidKun/XTabLayout

讲真的如果我使用这个,我会直接把他代码copy到自己的项目,不会去引入依赖。

PS:XTabLayout是基于design包中的TabLayout进行了功能的扩展,在保留原有功能的基础上,增加了修改选中项字体大小、修改指示器长度以及限制屏幕显示范围内显示的Tab个数。

 

实现方式四

Github开源库 https://github.com/chwzou/PagerSlidingTabStrip  很久之前的库

 

属性

 // 设置Tab底部选中的指示器 Indicator的颜色tabs.setIndicatorColor(Color.GREEN);//设置Tab标题文字的颜色tabs.setTextColor(Color.BLACK);// 设置Tab标题文字的大小tabs.setTextSize(16);//设置Tab底部分割线的颜色tabs.setUnderlineColor(Color.TRANSPARENT);// 设置点击某个Tab时的背景色,设置为0时取消背景色tabs.setTabBackground(0);// 设置Tab是自动填充满屏幕的tabs.setShouldExpand(true);//!!!设置选中的Tab文字的颜色!!!tabs.setSelectedTextColor(Color.GREEN);//tab间的分割线tabs.setDividerColor(Color.GRAY);//底部横线与字体宽度一致tabs.setIndicatorinFollower(true);//与ViewPager关联,这样指示器就可以和ViewPager联动tabs.setViewPager(viewPager);//源码里面的属性
private final PageListener              pageListener           = new PageListener();private       int                       currentPosition        = 0;private       int                       selectedPosition       = 0;private       float                     currentPositionOffset  = 0f;private       int                       indicatorColor         = 0xFF666666;private       int                       indicatorWidth         = 0;private       int                       indicatorHeight        = 8;private       int                       indicatorCorner        = 0;private       int                       underlineColor         = 0x1A000000;private       int                       dividerColor           = 0x1A000000;private       boolean                   shouldExpand           = false;private       boolean                   textAllCaps            = false;private       int                       scrollOffset           = 52;private       int                       underlineHeight        = 2;private       int                       dividerPadding         = 12;private       int                       tabPadding             = 20;private       int                       tabMargins             = 0;private       int                       dividerWidth           = 1;private       int                       tabTextSize            = 12;private       int                       tabTextColor           = 0xFF666666;private       int                       selectedTabTextColor   = 0xFF666666;private       Typeface                  tabTypeface            = null;private       int                       tabTypefaceStyle       = Typeface.NORMAL;private       int                       lastScrollX            = 0;private       boolean                   isCurrentItemAnimation = false;private       Paint                     rectPaint;private       Paint                     dividerPaint;private       int                       tabWidth;private       int                       rectPaintWidth;public        LinearLayout              tabsContainer;private       ViewPager                 pager;private       int                       tabCount;private       RectF                     indicateRectF;private       LinearLayout.LayoutParams defaultTabLayoutParams;private       LinearLayout.LayoutParams expandedTabLayoutParams;

 

自定义度极高,属于六年前的项目,使用的话需要注意一下API相关的问题,最好是把主要的代码复制出来,做自定义View。

 

 

PS:推荐使用MagicIndicator,容易扩展,自定义方便。

 

  相关解决方案