参考英文地址:Flutter — PageView with BottomNavigationBar
你可能早已经使用过BottomNavigation和PageView。
现在,我们将要一起使用这个两个组件。
第一步
创建一个BottomNavigationBar
和三个BottomNavigationBarItem
。
这个BottomNavigationBar
用于在应用的底部展示,用于视图的选择,通常大多是3个到5个之间,底部导航常由文本标签、图标或两者兼有的多种形式的项组成,提供了应用底层视图之间的快速导航,这个底部导航常常与 Scaffold
配合使用,这个脚手架提供了Scaffold.bottomNavigationBar
参数。
底部导航栏类型决定了这些导航项如何展示,如果没有指定,当少4个的时候,自动设置为 BottomNavigationBarType.fixed
,如果 fixedColor
指定了,将以该颜色渲染选中的导航项,未指定将会使用ThemeData.primaryColor
,导航栏的背景色,默认为(ThemeData.canvasColor)Material的背景色(不透明白色),当大于等于4个的时候,设置为BottomNavigationBarType.shifting
,所有的导航项被渲染为白色,导航栏的背景色与选中导航项的背景色一致,会fixed不同的是,每点击一导航项,会有一个动画效果。
这个BottomNavigationBarItem
类很少单独使用。通常嵌入在上面的一个底部导航小部件中。
1 | int bottomSelectedIndex = 0; |
第二步
使用3个状态组件创建PageView。
PageView
是按页展示的滚动列表。
页面视图的子组件被强制与视图窗口的大小保持一致,你可以使用PageController
来控制在这个视图中可见的页面,视窗。
您可以使用PageController
来控制哪个页面在视图中可见。除了能够控制PageView中内容的像素偏移量之外,PageController
还允许您以页面的形式控制偏移量,即以视图窗口大小为增量。
PageController
也用于控制PageController.initialPage
,它决定了在初次构造PageView时显示哪个页面,以及PageController
,以及PageController.viewportFraction
,它决定了页面大小占视窗大小的百分比,keepPage参数决定了是否使用PageStorage
保存当前页面。
第一个页面,red.dart
1 |
|
第二个页面,blue.dart
1 | class Blue extends StatefulWidget { |
第三个页面,yellow.dart
1 | class Yellow extends StatefulWidget { |
我们需要传入PageController
来控制初始化选择的页面,以及手动地从一个导航到另一页面。
1 | PageController pageController = PageController( |
在build
方法体中调用buildPageView
。
1 |
|
第三步
我们需要做一些技巧来管理PageView
和BottomNavigationBar
的同步。
在当前应用程序中的状态中,有两个问题:
- 当我们滑动导航栏时,它的选择不会改变。
- 当我们选择其他的底部导航栏项时,我们的页面视图不会滚动。
为了解决第一问题,我们可以使用由PageView
提供的onPageChanged
事件。
1 | void pageChanged(int index) { |
onPageChanged
事件将会给我们当前页面的索引,我接受到页面索引在setState
中设置bottomSelectedIndex
索引,这样我们的底部的选择就会自动变化。
现在修复第二个问题,如果我们选择任意的BottomNavigationBarItem
,然后我们的PageView
应该自动滑动,为了修复这个问题,我们需要使用BottomNavigationBar
的onTap
事件。
1 |
|
类似于onPageChanged
事件,onTap
事件也为我们提供了当前触碰的一个索引,这样基于这个索引设置bottomSelectedIndex
,然后使用pageController.animateToPage
移动选中的页面,其接受三个参数,index
,duation
,curve
,返回一个future
。
1 | pageController.animateToPage(index, duration: Duration(milliseconds: 500), curve: Curves.ease); |
最终的main.dart
文件如下:
1 |
|