资讯展示类的APP一般都是采用ViewPager+Fragment+TabLayout实现滑动页面并联动底部导航的效果,我之前开始也是采用这种方式,这种方式有个弊端就是需要自己根据页面的滑动控制底部导航栏的按钮颜色的切换。
![7e38a90a2cd58f69425db08b339c5dfc.png](https://i-blog.csdnimg.cn/blog_migrate/95bf57a1079290ed9fe053fd358a674a.jpeg)
后来Google出了新的解决方案,TabLayout有了替代品BottomNavigationView,这个控件的好处在于页面滑动是开发者无需自己管理导航栏的颜色切换,并且这个控件还添加了切换动画,从此TabLayout就在我的项目中彻底消失。
好了,不多说了,看下这个APP的主体框架怎么实现的吧!
1、xml视图文件
<?xml version="1.0" encoding="utf-8"?>
线性布局下面就放两个控件,一个是ViewPager,一个是前文提到的BottomNavigationView。NoScrollViewPager这个是自定义控件,名字上来看就知道这个ViewPager是无法左右滑动的,实现起来很简单,重写onTouchEvent方法即可,如下:
/** * 是否消费事件 * 消费:事件就结束 * 不消费:往父控件传 */ @Override public boolean onTouchEvent(MotionEvent ev) { //return false;// 可行,不消费,传给父控件 //return true;// 可行,消费,拦截事件 //super.onTouchEvent(ev); //不行, //虽然onInterceptTouchEvent中拦截了, //但是如果viewpage里面子控件不是viewgroup,还是会调用这个方法. if (isScroll) { return super.onTouchEvent(ev); } else { return true;// 可行,消费,拦截事件 } }
2、Kotlin逻辑文件
先将后续会用到的几个Fragment一一添加进集合备用
private lateinit var fragmentList: ArrayList override fun initData() { fragmentList = ArrayList() fragmentList.add(HomePageFragment()) fragmentList.add(DiscoverFragment()) fragmentList.add(SettingsFragment())}
将ViewPager+Fragment+BottomNavigationView三者关联起来
override fun initEvent() { bottomNavigation.setOnNavigationItemSelectedListener { menuItem -> when (menuItem.itemId) { R.id.nav_home -> mainViewPager.currentItem = 0 R.id.nav_discover -> mainViewPager.currentItem = 1 R.id.nav_settings -> mainViewPager.currentItem = 2 } false } mainViewPager.adapter = ViewPagerAdapter(fragmentList, supportFragmentManager) mainViewPager.offscreenPageLimit = fragmentList.size//缓存页数 mainViewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrollStateChanged(state: Int) { } override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { } override fun onPageSelected(position: Int) { if (menuItem != null) { menuItem!!.isChecked = false } else { bottomNavigation.menu.getItem(0).isChecked = false } menuItem = bottomNavigation.menu.getItem(position) menuItem!!.isChecked = true } }) }
其中menuItem我们需要在资源文件夹(res)下面新建一个menu文件夹,然后再在里面建一个menu文件,这个文件就是用来关联底部导航的
<?xml version="1.0" encoding="utf-8"?>
到此,这个APP的主体框架就搭建完毕,接下来该为其“添砖加瓦”,完善其他功能了