自定义TabLayout的Indicator
最近项目要使用类似TabLayout的控件,其实我感觉就是TabLayout只是换了一个Indicator,先说一说TabLayout这是Android Support Design的控件要使用的同学们应导入Design库在Gradle中在dependencies加入下面代码同步Gradle就可以使用了,Design里面还有很多有意思的东西推荐大家都看看。
1 | compile 'com.android.support:design:23.1.1' |
想改变TabLayout Indicator还是有点麻烦的,主要是TabLayout没有暴露出一些东西,这就导致我们在自定义Indicator的时候不是那么的方便呢。我的想法是在TabLayout后面加一个View来跟随TabLayout自己来画Indicator,实现方法有很多我只给大家提供一个思路,下面是布局方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | < FrameLayout android:layout_width="match_parent" android:layout_height="60dp"> < com.indicator.ShapeIndicatorView //自定义Indicator android:id="@+id/custom_indicator" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="10dp" app:fullColor="@android:color/holo_blue_dark" /> < android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="match_parent"></ android.support.design.widget.TabLayout > </ FrameLayout > |
用一个FrameLayout包含一个TabLayout与一个自定义的Indicator, ShapeIndicatorView的代码包含三个部分,设置TabLayout,设置ViewPager,然后将TabLayout与ViewPager组合起来。
下面代码说明它们是如何组合的,其实TabLayout有一个setupWithViewPater方法可以直接设置ViewPager但这样会产生一个问题,TabLayout内部会为ViewPager添加一个自身的OnViewPagerScrollListener,而我们自己定义的也会添加一个listener这就会导致有一些冲突我的解决办法是不为TabLayout设置ViewPager将ViewPager设置在自定义的View由我们管理TabLayout与ViewPager的切换工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.container); mViewPager.setAdapter(mSectionsPagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout); ShapeIndicatorView shapeIndicatorView = (ShapeIndicatorView) findViewById(R.id.custom_indicator); tabLayout.setTabsFromPagerAdapter(mViewPager.getAdapter()); tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); shapeIndicatorView.setupWithTabLayout(tabLayout); shapeIndicatorView.setupWithViewPager(mViewPager); |
准备好上面的工作后再看ShapeIndicatorView内部的代码。首先将TabLayout原生的Indicator的颜色设置为不可见,然后设置个listener监听Tab切换事件, 最后要添加一个全局的滚动listener如果TabLayout的Mode是SCROLLABLE的话这是有必要的,因为我们的Indicator也要跟直滚动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public void setupWithTabLayout( final TabLayout tableLayout){ mTabLayout = tableLayout; tableLayout.setSelectedTabIndicatorColor(Color.TRANSPARENT); tableLayout.setOnTabSelectedListener( this ); tableLayout.getViewTreeObserver().addOnScrollChangedListener( new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { if (mTabLayout.getScrollX() != getScrollX()) scrollTo(mTabLayout.getScrollX(), mTabLayout.getScrollY()); } }); ViewCompat.setElevation( this , ViewCompat.getElevation(mTabLayout)); tableLayout.post( new Runnable() { @Override public void run() { if (mTabLayout.getTabCount() > 0 ) onTabSelected(mTabLayout.getTabAt( 0 )); } }); //清除Tab background for ( int tab = 0 ; tab < tableLayout.getTabCount() ; tab++){ View tabView = getTabViewByPosition(tab); tabView.setBackgroundResource( 0 ); } } |
效果图
还有的一些就是协作方法就不贴出来呢,有兴趣的可以看源码。
https://github.com/yjwfn/tablayoutindicator.git
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?