效果图:
Home.dart
AppBarDemo.dart
Categroy.dart
底部导航基本架构参考:flutter实现底部导航
main.dart
import 'package:flutter/material.dart';
import 'routes/Routes.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
debugShowCheckedModeBanner: false, //去掉debug图标
initialRoute: '/', //初始化的时候加载的路由
// home: Tabs(), //将代码全部抽离出去成一个Tabs组件,再抽离成一个初始化路由组件,在上方 initialRoute: '/',
//配置命名路由
onGenerateRoute: oonGenerateRoute //将抽离出去的路由传值规范赋值给左边,而不是执行,记住喔!
);
}
}
Routes.dart
import '../pages/Tabs.dart';
import 'package:flutter/material.dart';
import '../pages/AppBarDemo.dart';
//配置路由
final routes={ //配置命名路由
'/':(context)=>Tabs(), //命名路由传值 arguments工具是必须的
'/appBarDemo':(context)=>AppBarDemoPage()
};
//固定写法
var oonGenerateRoute=(RouteSettings settings) {
// 统一处理
final String name = settings.name; //得到命名路由的名字,例如:'/form'
final Function pageContentBuilder = routes[name]; //得到命名路由的键去获取值,例如:(context)=>FormPage(),
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(context));
return route;
}
}
};
Tabs.dart
import 'package:flutter/material.dart';
import 'tabs/Category.dart';
import 'tabs/Home.dart';
import 'tabs/Setting.dart';
class Tabs extends StatefulWidget {
final index; //用来作为返回根路由时,判断要显示第几个底部导航项的坐标
Tabs({Key key,this.index=0}) : super(key: key); //可选参数,默认是0
@override
_TabsState createState() => _TabsState(this.index); //把当前坐标通过_TabsState构造方法传给_TabsState类
}
class _TabsState extends State<Tabs> {
int _currentIndex;
_TabsState(index){ //接收Tabs 类调用时,传过来的参数,赋值给 _currentIndex
this._currentIndex=index;
}
List _pageList = [ //先将所有页面放到List集合内
HomePage(),
CategoryPage(),
SettingPage()
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('FlutterDemo'),
),
body: this._pageList[this._currentIndex], //再根据下标获取对应页面设置到body 里
bottomNavigationBar: BottomNavigationBar( //自定义底部导航条
currentIndex: this._currentIndex, //配置对应的索引值选中
onTap: (int index){
setState(() { //改变状态
this._currentIndex=index; //更改选中的Tab坐标
});
},
// iconSize: 45.0, //Icon的大小,默认在20左右
fixedColor: Colors.red, //选中的颜色,默认是蓝色
items:[
BottomNavigationBarItem( //设置导航项
icon:Icon(Icons.home),
title: Text('首页')
),
BottomNavigationBarItem( //设置导航项
icon:Icon(Icons.category),
title: Text('分类')
),
BottomNavigationBarItem( //设置导航项
icon:Icon(Icons.settings),
title: Text('设置')
)
]
),
);
}
}
AppBarDemo.dart
import 'package:flutter/material.dart';
class AppBarDemoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController( //顶部导航切换
length: 2, //必须配置:顶部图标一共多少个
child: Scaffold(
appBar: AppBar(
title: Text('AppBarDemoPage'),
backgroundColor: Colors.red, //设置导航上的背景颜色
centerTitle: true, //设置:无论是在Android 还是 ios 上,标题都是居中显示
// leading: Icon(Icons.menu), //给导航左边添加图标,默认是返回图标,无法监听
// leading: IconButton(
// icon: Icon(Icons.menu), //给导航左边添加图标,默认是返回图标,可以监听
// onPressed: (){
// print('menu');
// },
// ),
// actions: <Widget>[ //右侧添加图标按钮
// IconButton(
// icon: Icon(Icons.search),
// onPressed: (){
// print('search');
// },
// ),
// IconButton( //右侧添加第二个图标按钮
// icon: Icon(Icons.settings),
// onPressed: (){
// print('settings');
// },
// )
// ],
bottom: TabBar(
tabs: <Widget>[ //配置Tabs菜单,系统会根据这里配置的是顺序对应下边body:TabBarView 里元素的顺序进行显示
Tab(text: '热门',),
Tab(text: '推荐',)
],
),
),
body: TabBarView(
children: <Widget>[
ListView(
children: <Widget>[
ListTile(
title: Text('第一个tab'),
),
ListTile(
title: Text('第一个tab'),
),
ListTile(
title: Text('第一个tab'),
)
],
),
ListView(
children: <Widget>[
ListTile(
title: Text('第二个tab'),
),
ListTile(
title: Text('第二个tab'),
),
ListTile(
title: Text('第二个tab'),
)
],
)
],
),
),
);
}
}
Home.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('跳转到appBar'),
onPressed: (){
//路由跳转
Navigator.pushNamed(context, '/appBarDemo');
},
)
],
),
);
}
}
Categroy.dart
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
@override
_CategoryPageState createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold( //在Scaffold 里再嵌套Scaffold
appBar: AppBar(
backgroundColor: Colors.black26,
/**
* 将顶部导航写在title里是为了防止,当Scaffold嵌套Scaffold时,发生两个顶部的bug,为了修复这个bug,
* 我们就可以把顶部导航条写在title里
*/
title: Row(
children: <Widget>[
Expanded(
child: TabBar(
indicatorColor: Colors.blue, //设置指示器的颜色
labelColor: Colors.blue, //设置:选中颜色
unselectedLabelColor: Colors.white, //设置:未选中颜色
indicatorSize: TabBarIndicatorSize.label, //选中时,底部指示条与文字一样长,默认是tab
tabs: <Widget>[
Tab(text: '热销'),
Tab(text: '推荐',),
Tab(text: '三',),
Tab(text: '四',)
],
),
)
],
),
),
body: TabBarView(
children: <Widget>[
ListView(
children: <Widget>[
ListTile(
title: Text('第一个tab'),
),
ListTile(
title: Text('第一个tab'),
),
ListTile(
title: Text('第一个tab'),
)
],
),
ListView(
children: <Widget>[
ListTile(
title: Text('第二个tab'),
),
ListTile(
title: Text('第二个tab'),
),
ListTile(
title: Text('第二个tab'),
)
],
),
ListView(
children: <Widget>[
ListTile(
title: Text('第三个tab'),
),
ListTile(
title: Text('第三个tab'),
),
ListTile(
title: Text('第三个tab'),
)
],
),
ListView(
children: <Widget>[
ListTile(
title: Text('第四个tab'),
),
ListTile(
title: Text('第四个tab'),
),
ListTile(
title: Text('第四个tab'),
)
],
)
],
),
),
);
}
}
Demo目录结构: