2020年,在这个不平凡的一年里,作为一名Android开发者,随着Flutter高热度的来临,深深体会到了Android市场的饱和,更何况我这种懒得要死菜狗子,只能被迫学习,于是近日学习了Flutter,准备做一些功能性的Flutter项目,一方面便于学习,另一方面也便于自己后期对Flutter项目的开发,狗哥写的文章适合初学者及其想快速上手的同胞们学习参考,废话少说,今天我们一起来制作APP的底部导航栏吧!
普通底部导航栏
首先请先看效果图
-
image
废话不多说上代码
我们首先看下main.dart代码
void main() {
runApp(MyApp());
}
///自定义组件 StatelessWidget(无状态组件)
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter底部导航栏",
home: Scaffold(
// appBar: AppBar(
// title: Text("Flutter底部导航栏"),
// ),
bottomNavigationBar: BottomNavigationWidget(),
),
theme: ThemeData.light(),
);
}
}
复制代码
main( )方法是Flutter 程序的主入口 ,MaterialApp 组件一般配合 Scaffold 组件一起使用,一般主要是用来搭建APP 的框架,比如AppBar , BottmNavigationBar 等,这里我们主要做底部导航栏;Scaffold 组件中有自带的 bottomNavigationBar 属性就是用来设置底部导航栏的,这里我们去自定义一个组件,其实就相当于写一个类,然后在类里面去去实现底部导航栏的操作,最终赋值在 bottomNavigationBar 这个属性上,因为 Flutter 中万物皆为组件,也称为Flutter开发为组件式开发,这里我们自定义了 BottomNavigationWidget 组件。
以下是我们自定义的 BottomNavigationWidget 组件代码。
import 'package:flutter/material.dart';
import 'bottom_navigation/home_screen.dart';
import 'bottom_navigation/email_screen.dart';
import 'bottom_navigation/pages_screen.dart';
import 'bottom_navigation/airplay_screen.dart';
///底部导航栏制做,
class BottomNavigationWidget extends StatefulWidget {
@override
_BottomNavigationWidgetState createState() => _BottomNavigationWidgetState();
}
class _BottomNavigationWidgetState extends State<BottomNavigationWidget> {
///定义底部导航栏字体的颜色
final _BottomNavigationColor = Colors.blue;
///需要点击的item索引
int _currentIndex = 0;
///定义装有 4 个页面组件用到的 List ,所以范型用的 Widget
List<Widget> mList = List();
///重写StatefulWidget抽象类中的initState()方法,用于初始化的操作
@override
void initState() {
///使用 List 的 ..add()方法,写法比逐个去 mList.add()要简单
mList
..add(HomeScreen())
..add(EmailScreen())
..add(PagesScreen())
..add(AirplayScreen());
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: mList[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
///这是添加的4个item
items: [ BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: _BottomNavigationColor,
),
title: Text(
"home",
style: TextStyle(color: _BottomNavigationColor),
)),
BottomNavigationBarItem(
icon: Icon(
Icons.email,
color: _BottomNavigationColor,
),
title: Text(
"email",
style: TextStyle(color: _BottomNavigationColor),
)),
BottomNavigationBarItem(
icon: Icon(
Icons.pages,
color: _BottomNavigationColor,
),
title: Text(
"pages",
style: TextStyle(color: _BottomNavigationColor),
)),
BottomNavigationBarItem(
icon: Icon(
Icons.airplay,
color: _BottomNavigationColor,
),
title: Text(
"airplay",
style: TextStyle(color: _BottomNavigationColor),
))
],
///item的索引赋值
currentIndex: _currentIndex,
///item点击事件
onTap: (int index) {
setState(() {
///当前索引等于点击后的item索引
_currentIndex = index;
});
},
),
);
}
}
复制代码
因为我们需要定义的组件是可变化的,所以我们继承了 StatefulWidget 组件 ,这里简单说下StatelessWdiget组件和 StatefulWidget 组件的区别。
- StatelessWdiget 组件:无状态的组件,复用某种组件。
- StatefulWidget 组件:有状态的组件,数据处理,逻辑处理。
这里我们就把一般App 使用的底部导航栏功能实现了,顺便还带有选中之后放大的效果。
自定义不规则底部导航栏
老规矩,先上效果图
-
image
一般我们做APP的都知道,很多APP 底部导航栏采用这样的样式,如果用原生开发还是比较费劲的,但是用Flutter 开发还是很便捷的,原理大概就是将 Flutter 中的 FloatActionButton 悬浮按钮融合到底部导航栏中去实现,上代码!
这里我们还是采用刚开始那段入口代码,只是我们的 bottomNavigationBar 属性实现的组件我们去单独定义,将这个自定义底部导航栏的功能单独写一个组件。
import 'dart:ui';
import 'package:flutter/material.dart';
import 'flutter/BottomAppBarDemo.dart';
import 'flutter/BottomNavigationWidget.dart';
import 'study/study.dart';
void main() {
runApp(MyApp());
}
///自定义组件 StatelessWidget(无状态组件)
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter底部导航栏",
home: Scaffold(
// appBar: AppBar(
// title: Text("Flutter底部导航栏"),
// ),
///自定义的BottomAppBarDemo组件
bottomNavigationBar: BottomAppBarDemo(),
),
theme: ThemeData.light(),
);
}
}
复制代码
来我们看自定义的 BottomAppBarDemo 组件。
import 'package:flutter/material.dart';
import 'bottom_navigation/each_view.dart';
///自定义不规则底部导航栏
class BottomAppBarDemo extends StatefulWidget {
@override
_BottomAppBarDemoState createState() => _BottomAppBarDemoState();
}
class _BottomAppBarDemoState extends State<BottomAppBarDemo> {
List<Widget> _eachView;
int _index = 0;
@override
void initState() {
super.initState();
_eachView = List();
_eachView
..add(EachViewState("Home"))
..add(EachViewState("email"))
..add(EachViewState("pages"))
..add(EachViewState("airplay"));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _eachView[_index],
floatingActionButton: FloatingActionButton(
///响应事件,push 生成新的页面,即点击中间的按钮跳转的页面
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
return EachViewState("这是新的页面");
}));
},
///长按
tooltip: "狗哥最帅",
child: Icon(
Icons.add,
color: Colors.white,
),
),
bottomNavigationBar: BottomAppBar(
color: Colors.white,
shape: CircularNotchedRectangle(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: Icon(Icons.home),
color: Colors.blue,
onPressed: () {
setState(() {
//手动赋值索引
_index = 0;
});
},
),
IconButton(
icon: Icon(Icons.email),
color: Colors.blue,
onPressed: () {
setState(() {
_index = 1;
});
},
),
IconButton(
icon: Icon(Icons.av_timer),
color: Colors.blue,
onPressed: () {
setState(() {
_index = 2;
});
},
),
IconButton(
icon: Icon(Icons.dashboard),
color: Colors.blue,
onPressed: () {
setState(() {
_index = 3;
});
},
)
],
),
),
///将FloatActionButton 与 BottomAppBar 融合到一起
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
复制代码
这里主要用到的 FloatActionButton 组件与底部导航栏融合的代码为:
///将FloatActionButton 与 BottomAppBar 融合到一起
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
复制代码
这就是 Flutter 中两种不同的底部导航栏功能的实现,以后狗哥将不定时间发文 Flutter 各种功能的实现及其原理,写到这里已是深夜,大佬们看到这里,如果觉得不错也可以支持下狗哥,给狗哥的文章点个 star ,毕竟这是狗哥的第一偏 Flutter 文章!代码如果有不合理的地方也可以指出来互相交流!
网友评论