应用内加个Tab实现左右滑动,已经是司空见惯,也有很多大佬进行了各种封装,(纯粹是做一下记录证明周末没有躺尸)。
首先是Android原生的TabLayout和ViewPager。
可参考API TabLayout
实现方式1
TabLayout + ViewPager + Fragment
1.两个Adapter的选用。
(一)FragmentPagerAdapter
viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
});
tabLayout.setupWithViewPager(viewPager);
(二)FragmentStatePagerAdapter
viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
@Override
public 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() {
@Override
public 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));
}
@Override
public 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);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
实现方式二
具体使用请去查看README.md
MagicIndicator 可以实现的功能,即使Demo里面没有你想要的功能,你可以通过继承SimplePagerTitleView实现自己的效果,还有一个比较酷的点是指示器。
跟Tablayout相比
使用上: 代码量都可以,如果加上自定义指示器和渐变效果完全可以碾压TabLayout
设计上:个人感觉模块划分很完美
效果:无论是直接用Demo还是自定义,遵守框架的设计都会很方便。
优点:指示器
上代码
CommonNavigator commonNavigator = new CommonNavigator(this);
commonNavigator.setAdjustMode(true);
commonNavigator.setAdapter(new CommonNavigatorAdapter() {
@Override
public int getCount() {
return mDataList == null ? 0 : mDataList.size();
}
@Override
public IPagerTitleView getTitleView(Context context, final int index) {// 相当于Tab
SimplePagerTitleView 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() {
@Override
public void onClick(View v) {
mViewPager.setCurrentItem(index);
}
});
return simplePagerTitleView;
}
@Override
public 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);
具体细节就不扯太多,总之这个库很强大。
实现方式三
讲真的如果我使用这个,我会直接把他代码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,容易扩展,自定义方便。