TabLayout + ViewPager + Fragment 实现方式总结

应用内加个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) {

            }
        });

实现方式二

使用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() {
            @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);

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

实现方式三

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,容易扩展,自定义方便。

发布了57 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37492806/article/details/98469634