应用内加个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,容易扩展,自定义方便。