基础结构篇
上一篇文章简单介绍了Flutter,接下来正式进入到Flutter仿美团项目开发,Github项目地址 。
首先对比一下效果图 (左侧为Flutter, 右侧为美团)
出于个人喜好,我习惯于将状态栏的颜色设为透明,此时状态栏将呈现appbar的背景色。
main.dart
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_meituan/src/language/chineseCupertinoLocalizations.dart';
import 'package:flutter_meituan/src/tabScaffold.dart';
void main() {
runApp(MyApp());
///如果是安卓平台,将状态栏颜色设为透明
if (Platform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle =
SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.white
),
debugShowCheckedModeBanner: false,
localizationsDelegates: [
ChineseCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
DefaultCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en'), // English
const Locale('zh'), // Chinese
],
home: TabScaffold(),
);
}
}
-
runApp方法是由异步实现的,所以runApp方法后面的if语句并不会在应用程序退出后执行,而是在发出启动MyApp的消息后立即执行。这里可以执行一些应用初始化工作,注意不要放在runApp方法之前,避免拖慢app启动速度。
-
接着在MyApp里返回一个MaterialApp,用于配置app颜色主题及国际化。theme参数接受一个ThemeData对象,在ThemeData对象里可以配置大部分Widget的默认颜色,如Scaffold的背景色等。这里我们将app主题颜色设为白色。Colors可以看作一个工具类,里面提供了常用的颜色,实际开发时可以通过Color类配置RGB色彩 如 Color.fromARGB(1, 200, 200, 200) ,第一个参数为透明度,后面三个参数对应RGB颜色分量。debugShowCheckedModeBanner属性用于控制是否在debug模式下在app右上角显示debug图标。localizationsDelegates属性配置国际化,需要在pubspec.yaml文件中添加依赖
dependencies: flutter: sdk: flutter flutter_localizations: //新添加的 sdk: flutter //新添加的
配置国际化后大部分 Material Widget 都会根据当前系统语言显示对应的文字及格式等。app内用到的字符 串也可以通过自己实现Localizations类在这里配置国际化,具体参考 官方国际化文档
-
supportedLocales属性用于注明已支持的语言。
-
home属性配置进入app时显示的第一个Widget,这里我们传入一个自定义的 TabScaffold Widget。
TabScaffold.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_meituan/src/Route/findPage.dart';
import 'package:flutter_meituan/src/Route/homePage.dart';
import 'package:flutter_meituan/src/Route/orderPage.dart';
import 'package:flutter_meituan/src/Route/userPage.dart';
class TabScaffold extends StatefulWidget {
@override
_TabScaffoldState createState() => _TabScaffoldState();
}
class _TabScaffoldState extends State<TabScaffold> {
int _selectedIndex = 0;
final bodys = [
HomePage(), //home界面
FindPage(), //发现界面
OrderPage(), //订单界面
UserPage(), //用户界面
];
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: CupertinoTabBar(
backgroundColor: Colors.white, //底部导航栏背景色
activeColor: Colors.teal, //被选中的tabbar背景色
currentIndex: _selectedIndex, //当前被选中的tabbar的序号
onTap: (index) { //tabbar点击事件
setState(() {
_selectedIndex = index; //将当前被选中序号更新成被点击的tabbar的序号,并通知界面刷新
});
},
items: const <BottomNavigationBarItem>[ //底部显示的tabbar
BottomNavigationBarItem(
icon: Icon(
Icons.home, //tabbar图标
),
title: Text("首页")), //tabbar标题
BottomNavigationBarItem(
icon: Icon(
Icons.find_in_page,
),
title: Text("发现")),
BottomNavigationBarItem(
icon: Icon(
Icons.assignment,
),
title: Text("订单")),
BottomNavigationBarItem(
icon: Icon(
Icons.account_box,
),
title: Text("我的")),
],
),
body: bodys[_selectedIndex], //底部导航栏对应的界面
);
}
}
- 底部导航栏 通过Scaffold的bottomNavigationBar属性可以很便捷的构建底部导航栏。这里我们传入一个IOS风格的CupertinoTabBar。
红色部分对应items, 其他部分对应body。首页对应的body中我们依旧使用了一个Scaffold Widget作为整个界面的骨架,灰色的部分对应appbar,绿色的部分对应body。
- 界面切换 通过在_TabScaffoldState类中增加_selectedIndex属性控制界面切换。当点击下方的导航栏时,触发CupertinoTabBar的onTab事件,onTab事件会接收当前被点击的导航栏的序号,通过调用setState方法更新_selectedIndex的值并通知Widget状态发生变化,Widget重新调用build方法构建界面,此时body属性就会显示对应的界面。
body: bodys[_selectedIndex],