项目框架搭建
Nealyang opened this issue · comments
准备工作
笔者 Flutter 版本及环境信息:Channel beta, v0.11.9, on Mac OS X 10.14.1 18B75
版本更新向前兼容,笔者更新版本后,项目依旧运行如初。目前笔者的flutter版本信息为:
Flutter 1.0.0 • channel beta • https://github.com/flutter/flutter.git
Framework • revision 5391447fae (5 days ago) • 2018-11-29 19:41:26 -0800
Engine • revision 7375a0f414
Tools • Dart 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)
由于我们做App,并不会1:1模仿,而是要符合App的使用规范,所以这里,我们将不同的栏目作为bootomBar。
这里我们先起一个flutter项目,命名为flutter_juejin
建立如下目录文件:
后面我们的目录大致修改为:
定义每一个页面class
- pages/activityPage.dart
import 'package:flutter/material.dart';
class ActivityPage extends StatefulWidget {
_ActivityPageState createState() => _ActivityPageState();
}
class _ActivityPageState extends State<ActivityPage> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('活动'),
);
}
}
- pages/bookPage.dart
import 'package:flutter/material.dart';
class BookPage extends StatefulWidget {
_BookPageState createState() => _BookPageState();
}
class _BookPageState extends State<BookPage> {
@override
Widget build(BuildContext context) {
return new DefaultTabController(
length: 3,
child: new Scaffold(
appBar: new AppBar(
backgroundColor: Colors.orangeAccent,
title: new TabBar(
tabs: [
new Tab(
child:new Column(
children:<Widget>[
new Icon(Icons.directions_car),
new Text('Car')
]
)
),
new Tab(
child:new Column(
children:<Widget>[
new Icon(Icons.directions_transit),
new Text('transit')
]
)
),
new Tab(
child:new Column(
children:<Widget>[
new Icon(Icons.directions_bike),
new Text('bike')
]
)
),
],
indicatorColor: Colors.white,
),
),
body: new TabBarView(
children: [
new Icon(Icons.directions_car),
new Icon(Icons.directions_transit),
new Icon(Icons.directions_bike),
],
),
),
)
;
}
}
由于小册页面会有一个tab,我们暂时先拟定一个tab界面,后面再修改,你也可以暂时先像activityPage那样写个text上去
- pages/indexPage.dart
import 'package:flutter/material.dart';
class IndexPage extends StatefulWidget {
_IndexPageState createState() => _IndexPageState();
}
class _IndexPageState extends State<IndexPage> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('IndexPage'),
);
}
}
- pages/pinsPage.dart
import 'package:flutter/material.dart';
class PinsPage extends StatefulWidget {
_PinsPageState createState() => _PinsPageState();
}
class _PinsPageState extends State<PinsPage> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('沸点'),
);
}
}
- pages/reposPage.dart
import 'package:flutter/material.dart';
class ReposPage extends StatefulWidget {
_ReposPageState createState() => _ReposPageState();
}
class _ReposPageState extends State<ReposPage> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('开源库'),
);
}
}
然后我们在pages/myApp.dart中定义一个class,引入到main.dart中
- pages/mian.dart
import 'package:flutter/material.dart';
import './pages/myApp.dart';
void main() => runApp(MyApp());
编写入口文件 myApp.dart
- pages/myApp.dart
为了方面后面扩展,我们这里使用StatefulWidget
class MyApp extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
}
在 State中,我们定义如下:
final TextStyle tabTextStyleNormal =
TextStyle(color: const Color(0xffdddddd));
final TextStyle tabTextStyleSelected =
TextStyle(color: const Color(0xff4d91fd));
// 底部bar
final List<Tab> _bottomTabs = <Tab>[
Tab(
text: '首页',
icon: Icon(Icons.home),
),
Tab(
text: '沸点',
icon: Icon(Icons.chat),
),
Tab(
text: '小册',
icon: Icon(Icons.book),
),
Tab(
text: '开源库',
icon: Icon(Icons.bubble_chart),
),
Tab(
text: '活动',
icon: Icon(Icons.local_activity),
),
];
var _body;
List _appBarTitles = ['首页', '沸点', '小册', '开源库', '活动'];
上面定义了一些我们页面会使用到的一个变量,当然,页面顶部需要引入我们之前写好的一些页面
import 'package:flutter/material.dart';
import './indexPage.dart';
import './pinsPage.dart';
import './bookPage.dart';
import './reposPage.dart';
import './activityPage.dart';
在bottomNavigationBar
中我们需要使用TabBar
,所以在定义变量的时候,别忘记了加一个Controller
这里说一下一个VSCode的小技巧,当鼠标悬停到Widget的时候,我们可以看到这个Widget都有哪些属性,
Controller其实也可以说不需要,因为他的作用就是定义底部bar的长度,加上它后,我们可以通过setState来改变底部的菜单按钮,更多的使用介绍,大家可以查看Flutter的api。
顺便说下对于必须的属性,编译器会给我们对应的提示的。后面我们会遇到。
这里我们添加Controller
(万一后面我们会改变底部bar的长度呢,当然,能用StatelessWidget的最好用StatelessWidget,性能,你懂得)
TabController _tabController;
@override
void initState() {
// TODO: implement initState
super.initState();
_tabController =
new TabController(vsync: this, length: _bottomTabs.length);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
基本准备工作都有了,然后我们来写我们的build方法吧
@override
Widget build(BuildContext context) {
return Container(
child: MaterialApp(
theme: ThemeData(primaryColor: const Color.fromRGBO(77, 145, 253, 1.0)),
home: Scaffold(
appBar: AppBar(
title: Text('Title'),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
IndexPage(),
PinsPage(),
BookPage(),
ReposPage(),
ActivityPage()
],
),
bottomNavigationBar: new Material(
color: Theme.of(context).primaryColor,
child: TabBar(
tabs: _bottomTabs,
controller: _tabController,
indicatorColor: Colors.white,
),
),
),
),
);
}
Scaffold
是Material提供的一个类似HTML的架构,其中包括header、body差不多
这次,我们app的基础结构就都已经搭建起来了。后面需要调整的时候我们再做相应调整,包括项目的目录结构后面肯定会调整的。
后面会介绍目录部分的跳转和添加
总结
这一节中,你应该学会如何
- 定义新页面
- 顶部tab
- bottomNavigationBar
- VSCode的一些使用技巧
这一节中,鼓励大家自己敲代码,代码地址将在下一节中给出。