在iOS中,底部导航栏使用UITabBar就可以实现;在Flutter中,类似的效果可以通过BottomNavigationBar这个组件实现。
BottomNavigationBar有如下常见属性:
先上代码
//main.dart文件
import 'package:flutter/material.dart';
import 'pages/tabs/Tabbar.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Tabbar(),
);
}
}
//Tabbar.dart文件
import 'package:flutter/material.dart';
import 'Home.dart';
import 'Category.dart';
import 'Setting.dart';
class Tabbar extends StatefulWidget {
Tabbar({Key key}) : super(key: key);
_TabbarState createState() => _TabbarState();
}
class _TabbarState extends State<Tabbar> {
int _tabbarIndex = 0;//用于记录当前选中第几个item
List _tabPages = [//装载底部tabbar的item所对应的页面
HomePage(),
CategoryPage(),
SettingPage()
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("appbarTitle"),
),
body: this._tabPages[this._tabbarIndex],//显示当前选中的tabbatItem所对应的页面
bottomNavigationBar: BottomNavigationBar(
iconSize: 36,
fixedColor: Colors.pink,
type: BottomNavigationBarType.fixed,
currentIndex: this._tabbarIndex,//当前选中第几个item
onTap: (index){//点击回调
setState(() {//当需要改变页面中的参数值的时候,需要在该方法中更新数据,否则不会刷新页面
this._tabbarIndex = index;
});
},
items: [//配置底部导航栏的按钮列表
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首页")),
BottomNavigationBarItem(
icon: Icon(Icons.category), title: Text("分类")),
BottomNavigationBarItem(
icon: Icon(Icons.settings), title: Text("设置")),
],
),
);
}
}
运行效果如下:
有几点需要着重说明:
1,我们是给Scaffold组件中的 bottomNavigationBar 参数配置 BottomNavigationBar 类型的值,如下:
Scaffold(
appBar: AppBar(title: Text("appbarTitle")),
body: this._tabPages[this._tabbarIndex],
bottomNavigationBar: BottomNavigationBar(
......
),
);
2,为了使代码更清晰易读、简洁明了,我们需要将代码进行分离。我们自己写的所有的flutter代码,都放在工程的lib文件夹下面,所有的分类文件夹也都放在lib文件夹下。如下图所示,我在lib文件夹下新建了一个pages文件夹,用于装所有的页面;pages文件夹下面又创建了一个tabs文件夹,用于装载跟底部导航栏相关的页面。
文件分离之后,要想在其他的文件中使用分离出去的文件,就需要导入文件。
导入文件的时候是按路径导入,路径的写法是有规则的。
如果你导入的文件与当前文件属于同一级,也就是说在同一个文件夹下,那么直接写文件名即可,比如在Tabbar.dart中导入其他三个文件,就可以像下面这样写:
import 'Home.dart';
import 'Category.dart';
import 'Setting.dart';
如果你导入的文件file在文件夹A的里面,或者在A的子文件夹的里面,并且当前文件与A属于同一个路径级别,也就是说属于同一个文件夹下,那么要在当前文件中导入file的话,那么file的路径就需要从文件夹A依次往下去找。比如,我要在main.dart中导入tabbar.dart,由于main.dart与pages文件夹属于同级,所以要这样导入:
import 'pages/tabs/Tabbar.dart';
其实总而言之,在当前文件下导入某个文件,系统会首先在当前文件所在路径下寻找所要导入的文件路径,如果找不到,那么再到当前文件路径的上一层去寻找所要导入的文件路径,以此类推。
3,如果某个Widget是一个页面,那么该Widget最好是以Page结尾,如果我在本例中定义的首页、分类和设置页面,其定义分别如下:
//首页——Home.dart——HomePage
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Text("我是首页");
}
}
//分类——Category.dart——CategoryPage
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
CategoryPage({Key key}) : super(key: key);
_CategoryPageState createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return Text("我是分类页面");
}
}
//设置——Setting.dart——SettingPage
import 'package:flutter/material.dart';
class SettingPage extends StatefulWidget {
SettingPage({Key key}) : super(key: key);
_SettingPageState createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return Text("我是设置页面");
}
}
4,BottomNavigationBar里面有一个type属性。当底部导航栏的item很多或者尺寸比较大,从而导致BottomNavigationBar会被挤压,这时的展示效果就会很不美观,具体的效果大家可以去试一试,此时我们需要将type属性值设置为BottomNavigationBarType.fixed,这样底部导航栏就会自己进行适配,可以全部完美展示出来了。
以上。