Flutter是谷歌推出的一款全新的移动app SDK。它旨在帮助开发人员和设计师为Android和IOS开发现代应用程序。
在本系列中,我们将构建流行的即时通讯应用WhatsApp的UI
开始
首先,我们使用方便的CLI创建一个新的Flutter项目。
`$ flutter create whatsapp_ui_clone`
他将生成Android和IOS的项目文件
现在项目已生成,cd进入项目文件夹并运行Flutter run
$cd whatsapp_ui_clone && Flutter run`
默认情况下,Flutter会生成一个Counter应用程序,因此如果一切顺利,您应该在设备上看到这一点。
现在应用程序正在运行,让我们导航到lib文件夹并打开main.dart。 在这里,您可以看到默认应用程序的代码。 我们将删除所有内容,以便我们留下一个空白文件。
让我们首先导入flutter的material package。 此软件包包含一组按照Google的material design guidelines的预制小部件。
`import 'package:flutter/material.dart';`
很好! 随着包导入,我们现在转到 main 函数。 应用程序启动时将会走这里。
在 main.dart, 添加
```
void main(){
}
```
接下来,我们在main中指定runApp方法
```
void main(){
runApp(
);
}
```
可以为小部件MaterialApp分配一些属性。 出于我们的目的,我们只会使用home,theme和title。 修改现有代码,使其看起来像这样。
```
void main() {
runApp(
new MaterialApp(
home: new WhatsAppUiClone(), //new
title: 'WhatsApp', // new
theme: new ThemeData( //new
primaryColor: new Color(0xff075E54), //new
accentColor: new Color(0xff25D366), //new
),
));
}
```
上面的代码为我们的应用程序设置了一些属性。 Title为应用程序提供了标题,home为其分配了一个主页,theme设置了一些全局样式规则。
是时候创建WhatsAppUiClone类了。 在main方法下,我们创建一个名为WhatsAppUiClone的新类,并让它扩展StatefulWidget。
```
class WhatsAppUiClone extends StatefulWidget {
_WhatsAppUiClone createState() => new _WhatsAppUiClone();
}
class _WhatsAppUiClone extends State {
@override
Widget build(BuildContext context) {
return new Scaffold(
);
}
}
```
在Flutter中,有两种类型的小部件,有状态和无状态。 上面的代码使用Stateful变体。 如您所见,它分三步创建。 首先,在第1行,定义类名,然后是关键字Extends StatefulWidget。 然后在第二行,创建状态。 最后,在第五行创建另一个类,这次使用用于创建状态的名称。 这个类扩展了State。
我们现在可以开始创建appBar了。 在_WhatsAppUiClone中,添加以下行
```
class _WhatsAppUiClone extends State with SingleTickerProviderStateMixin { //modified
TabController _tabcontroller; //new
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: new Text('WhatsApp'),
elevation: 0.7,
bottom: new TabBar(
controller: _tabcontroller,
indicatorColor: Colors.white,
tabs: [
new Tab(icon: new Icon(Icons.camera_alt)),
new Tab(text: 'CHATS',),
new Tab(text: 'STATUS',),
new Tab(text: 'CALLS',)
],
),
),
);
}
}
```
太棒了! 只需几行代码,稍作修改,我们就创建了一个带有底部导航标签的素材应用栏。 该类被修改为包含SingleTickerProviderStateMixin,它是TabBar使用的动画属性。 接下来,我们返回了一个新的Scaffold,它是材料包中的一个小部件。 Scaffold为我们的应用程序添加不同的API,如AppBar,Tabs,Drawer等...要了解更多信息,请参阅https://docs.flutter.io/flutter/material/Scaffold-class.html。
在Scaffold内部,我们使用appBar属性来创建AppBar。 然后将背景颜色设置为之前在MaterialApp小部件的theme属性中定义的主要颜色。 作为appBar的一部分,我们使用bottom属性来创建TabBar。 TabBar包含一些属性,例如指示器颜色,我们也定义了控制器、Tab类型的小部件,选项卡将采用数组。 这里设置了四个选项卡。
有了这个,我们就可以创建不同的页面了。 现在,我们将创建一个显示一些文本的小部件。 在我们的lib文件夹中,创建一个名为pages的新文件夹。 在页面内部,我们创建了四个名为call_history.dart,camera_page.dart,chat_screen.dart和status_page.dart。 这些文件将是不同的tab主体。
对于call_history,我们添加以下行
```
import 'package:flutter/material.dart';
class CallHistory extends StatelessWidget {
@override
Widget build(BuildContext context){
return new Container(
child: new Center(
child: new Text('Time to make history...', style: new TextStyle(fontSize: 20.0),),
)
);
}
}
```
在camera_page中我们添加
```
import 'package:flutter/material.dart';
class CameraPage extends StatelessWidget {
@override
Widget build(BuildContext context){
return new Container(
child: new Center(
child: new Text('Camera Here! ', style: new TextStyle(fontSize: 20.0),),
)
);
}
}
```
对于 chat_screen
```
import 'package:flutter/material.dart';
class ChatScreen extends StatelessWidget {
@override
Widget build(BuildContext context){
return new Container(
child: new Center(
child: new Text('Red Squadron report in... ', style: new TextStyle(fontSize: 20.0),),
)
);
}
}
```
最后是status_page
```
import 'package:flutter/material.dart';
class StatusScreen extends StatelessWidget {
@override
Widget build(BuildContext context){
return new Container(
child: new Center(
child: new Text('Red Five reporting...', style: new TextStyle(fontSize: 20.0),),
)
);
}
}
```
有了所有组件,就可以连接并查看结果了。 回到main.dart,修改文件使其看起来像这样
```
import 'package:flutter/material.dart';
import './pages/camera_page.dart' ; //new
import './pages/chat_screen.dart' ; //new
import './pages/status_page.dart' ; //new
import './pages/call_history.dart' ; //new
void main() {
runApp(
new MaterialApp(
home: new WhatsAppUiClone(),
title: 'WhatsApp',
theme: new ThemeData(
primaryColor: new Color(0xff075E54),
accentColor: new Color(0xff25D366),
),
));
}
class WhatsAppUiClone extends StatefulWidget {
_WhatsAppUiClone createState() => new _WhatsAppUiClone();
}
class _WhatsAppUiClone extends State with SingleTickerProviderStateMixin {
TabController _tabcontroller;
//new
@override
void initState() {
super.initState();
_tabcontroller = new TabController(
vsync: this,
length: 4,
);
}
//new
@override
void dispose() {
super.dispose();
_tabcontroller.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
backgroundColor: Theme.of(context).primaryColor,
title: new Text('WhatsApp'),
elevation: 0.7,
bottom: new TabBar(
controller: _tabcontroller,
indicatorColor: Colors.white,
tabs: [
new Tab(icon: new Icon(Icons.camera_alt)),
new Tab(text: 'CHATS',),
new Tab(text: 'STATUS',),
new Tab(text: 'CALLS',)
],
),
),
//new
body: new TabBarView(
controller: _tabcontroller,
children: [
new CameraPage(),
new ChatScreen(),
new StatusScreen(),
new CallHistory()
],
),
);
}
}
```
从顶部开始向下工作,我们将刚创建的四个文件导入main.dart。 接下来,我们覆盖Flutter的两个生命周期方法。 在initState方法中,我们将之前创建的_tabcontroller设置为新的TabController。 选项卡的数量在此处设置。 向下移动,我们再次覆盖生命周期方法,这次是dispose。 最后,在Scaffold中,我们使用body属性并将其设置为新的TabBarView。 TabBarView使用与以前相同的控制器,并将我们创建的四个不同的类作为其子项。