Android 底部导航栏(三、ViewPager+TabLayout+Fragment)简单易懂
创始人
2024-04-03 18:31:29

底部导航栏在Android应用中随处可见,今天使用ViewPager+TabLayout+Fragment这三个控件来实现此功能。

前面使用了另外两个方法来实现导航栏,不过我还是更喜欢Viewpager,代码也少,毕竟前两个不能左右滑动。

Android 底部导航栏(一、BottomNavigationView+Menu+Fragment)_&岁月不待人&的博客-CSDN博客_android 底部导航栏现在常用的App主页都会有一个底部导航栏,根据需求也使用过好几种方法进行实现,于是想着还是总结一下,今天还写一个简单的BottomNavigationView方法来实现这个功能它是android原生的一个底部导航框架,一般和Fragment一起使用。xml布局:最外层的layout不用管,那是databinding框架的根布局,主要的布局FrameLayout来装载fragment列表,BottomNavigationView实现底部导航栏,最后监听绑定实现点击切换其中BottomNavigationhttps://blog.csdn.net/LoveFHM/article/details/125498372?spm=1001.2014.3001.5501

Android 底部导航栏(二、自定义View+Fragment)_&岁月不待人&的博客-CSDN博客总结:我这上面只实现了简单的点击切换,用自定义View来实现底部导航栏,很自由,可以实现一些稀奇古怪的需求,但是很多方法的回调,切换时的动画,就需要自己去实现,可能会相对复杂一些。最后加上Fragment的切换,点击监听等等,坏处的话就是自己写的,可能没有封装好的那么完善,很多方法,状态需要自己去写。上一片文章用的是BottomNavigationView+Menu+Fragment,但是可能有时候需求不一样,menu的样式不太够,所以需要自定义View来实现。https://blog.csdn.net/LoveFHM/article/details/127651226?spm=1001.2014.3001.5501

一、基本介绍

ViewPager:Android 3.0后引入的一个UI控件——ViewPager(视图滑动切换工具),Viewpager使用起来就是我们通过创建adapter给它填充多个view,左右滑动时,切换不同的view。Google官方是建议我们使用Fragment来填充ViewPager的,这样 可以更加方便的生成每个Page,以及管理每个Page的生命周期。可以用来主页/模块切换,图片轮播,新手引导等等。

ViewPager 全面总结_淡然一笑、的博客-CSDN博客_viewpager

TabLayout:TabLayout提供了一个水平布局用于展示tabs,继承自HorizontalScrollView。TabLayout一般结合ViewPager+Fragment的使用实现滑动的标签选择器。

Android控件-TabLayout使用介绍_Android开发猿的博客-CSDN博客_tablayout

Fragment:Fragment可以说是轻量级的Activity,是Android3.0新增的概念。这个就很基础了,不给链接了。

二、实现原理

Fragment用于承载和展示内容,Viewpager用于界面的切换,TabLayout用于展示导航栏和点击事件通知ViewPager切换页面。

三、实现过程

第一步:先拉界面哦




第二步:业务代码,就是初始化这两个控件,tablayout初始化item,设置属性,使用tabLayout.setupWithViewPager(viewPager)绑定viewpager,然后往Viewpager里面加fragment列表,然后给viewpager设置fragment。(kotlin实现,如果你是java代码,拷进项目它会自动转码为java,布局绑定用的databinding,没用过看核心代码就行了)

class NavViewPagerTabActivity : BaseBindActivity() {override val layout: Intget() = R.layout.nav_viewpager_tablayout_activity_layoutprivate lateinit var homeFragment: HomeFragmentprivate lateinit var toolsFragment: ToolsFragmentprivate lateinit var relaxFragment: RelaxFragmentprivate lateinit var viewPager: ViewPagerprivate lateinit var tabLayout: TabLayoutprivate lateinit var meFragment: MineFragmentprivate lateinit var playFragment: PlayFragmentprivate lateinit var fragments: Arrayprivate val titles = arrayOf("首页", "视频", "用户")override fun initView() {initFragment()//初始化fragment列表viewPager = mBinding.fragmentContainerViewpagertabLayout = mBinding.navTablayouttabLayout.setupWithViewPager(viewPager)//绑定viewpager
//        for (element in titles) tabLayout.addTab(tabLayout.newTab().setText(element))viewPager.adapter = object :FragmentPagerAdapter(supportFragmentManager,BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT){override fun getCount(): Int {return fragments.size}override fun getItem(position: Int): Fragment {return fragments[position]}override fun getPageTitle(position: Int): CharSequence {return titles[position]}}}private fun initFragment() {homeFragment = HomeFragment()toolsFragment = ToolsFragment()relaxFragment = RelaxFragment()meFragment = MineFragment()playFragment = PlayFragment()
//        fragments = arrayOf(homeFragment, toolsFragment, playFragment, relaxFragment, meFragment)fragments = arrayOf(homeFragment, toolsFragment, meFragment)}
}

eg:可以看到我把上面的这行代码注释,但是运行出来,tab是添加上了,为什么呢?

// for (element in titles) tabLayout.addTab(tabLayout.newTab())

原因很简单,是在tabLayout.setupWithViewPager的时候,TabLayout中先将所有tabs remove了,然后取的PagerAdapter中的getPageTitle返回值添加的tab。就是在给ViewPager设置Adapter的时候,一定要重写getPageTitle(int position)方法,不然TabLayout中的标签是看不到的,即使在addTab时newTab().setText(tabs[i])也没用。

这样就简单的实现了导航栏!可以单独为viewpager和tablayout添加监听事件,并且绑定也只需要一行代码,可以实现左右滑动切换界面,当然,如果想禁止左右滑的触摸事件也可以对viewpager事件作拦截。关于viewpager和tablayout,他们还有很多属性可以去配置,如果想详细了解的可以去看上面的两个链接去学习一下!

实现效果:

 

进阶知识点一:

为tablayout添加监听事件:

tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {override fun onTabSelected(tab: TabLayout.Tab?) {TODO("Not yet implemented")}override fun onTabUnselected(tab: TabLayout.Tab?) {TODO("Not yet implemented")}override fun onTabReselected(tab: TabLayout.Tab?) {TODO("Not yet implemented")}})

 为ViewPager添加监听事件:

viewPager?.setOnPageChangeListener(object : ViewPager.OnPageChangeListener {override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}override fun onPageSelected(position: Int) {}override fun onPageScrollStateChanged(state: Int) {}})

进阶知识点二:

为TabLayout设置自定义View,有时候底部导航栏可能不只是文字,他可能是图片和文字混合,可能点击后有图片,文字的大小变化,那么就需要为其单独配置view,并在监听事件里重新绘制界面。

这儿我展示一份项目里的代码:

 override fun onTabSelected(tab: TabLayout.Tab) {viewPager?.currentItem = tab.positionval customView = tab.customViewif (tab.position == 0) {//如果是第一个tabif (customView == null) tab.setCustomView(R.layout.tab_text_layout)//设置布局val textView = customView?.findViewById(R.id.text1)textView?.text = titles[tab.position].i18n()textView?.setTextAppearance(requireContext(), R.style.TabLayoutTextSelected)//设置点击后的文本格式val point = customView?.findViewById(R.id.point_1)//这是tab右上角的红点val layoutParams = RelativeLayout.LayoutParams(SizeUtils.dp2px(8f), SizeUtils.dp2px(8f))layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP)layoutParams.addRule(RelativeLayout.END_OF, R.id.text1)layoutParams.setMargins(5, 0, 0, 0)point?.layoutParams = layoutParams} else {if (customView == null) tab.setCustomView(R.layout.tab_text_layout2)val textView = customView?.findViewById(R.id.tab_text2)textView?.text = titles[tab.position].i18n()textView?.setTextAppearance(requireContext(), R.style.TabLayoutTextSelected)}}

相关内容

热门资讯

财联社1月8日早间新闻精选 转自:财联社【财联社1月8日早间新闻精选】 1、工业和信息化部等八部门印发《“人工智能+制造”专项行...
国家医保局:2028年前全面推... 转自:北京日报客户端今后看病缴费将不用再为排长队发愁了。1月8日,国家医保局发布通知,将在全国范围内...
新闻分析丨格陵兰岛为何让美国如... 来源:新华社新华社北京1月7日电 新闻分析|格陵兰岛为何让美国如此垂涎新华社记者林昊美军强行控制委内...
数字人主播纳入监管 “会员降权...   市场监管总局和国家网信办近日联合发布《网络交易平台规则监督管理办法》《直播电商监督管理办法》。这...
突破困境 “丫邦”组合更加坚定 北京时间1月7日,马来西亚羽毛球公开赛混双首轮,2号种子蒋振邦/魏雅欣2比0击败印度组合卡普尔/加德...