目录
成功运行了第一个项目,那么这一节我们来了解一下 Flutter 的文档目录,以及默认模板工程-计数器的 main 文件 。
计数器 Demo.png
Flutter 工程文件目录结构
工程文件目录.png文件 | 说明 |
---|---|
android | Android 平台相关代码 |
ios | iOS 平台相关代码 |
lib | Flutter 相关代码,主要代码存放在这里 |
main.dart | 工程入口文件 |
test | 测试代码 |
pubspec.yaml | 配置文件,一般存放一些第三方库的代码 |
Flutter 入口 main.dart 文件
main.dart 是整个项目的入口,一切从这里开始。
入口方法
import 'package:flutter/material.dart';
//导入的包路径
void main() {
runApp(MyApp());
}
- main() 方法是 Dart 的入口方法
- runApp() 方法是 Flutter 的入口方法
- MyApp() 是工程打开的第一个组件
根组件
在 Flutter 中所有 UI 都是由组件(Widget)构成的,所以主页面也就是一个组件(Widget)。
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
- class MyApp:该组件名称,也是类名。
- extends StatelessWidget:继承的组件为 StatelessWidget,该组件后面具体讲。
- Widget build(BuildContext context):StatelessWidget 组件的方法,在这里返回的即为 MyApp 组件的布局。
- MaterialApp:这是一个 Material Design 风格的根控件,如果我们想使用其他已经封装好的 Material Design 风格的 Widget,就必须使用 MaterialApp。
- title、theme、home:组件可以设置的属性,与 js 中属性相似。
- home:Widget 类型,主界面
主布局
上面根组件(暂且这么叫)MyApp 中,home 的值 MyHomePage 即为计时器的主页面,这里我们看一下 MyHomePage 中都有什么吧。
- StatefulWidget
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
//创建 _MyHomePageState()
}
这里主要是 StatefulWidget 组件的使用,这个放在后面和上边的 StatelessWidget 一起讲,这里只需要知道创建了 _MyHomePageState() 即可。
- State
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
// 创建 int 型变量 _counter,默认值为 0
void _incrementCounter() { //定义方法 _incrementCounter()
setState(() {
// RN 中也有 setState 方法,
// 这个方法的作用是,在这里面对前边定义的变量(如 _counter)改变值,
// 之后使用这个变量(如 '$_counter',)的地方的值会立刻变化,不需要再获取到控件设置新值,
// 这就是响应式编程。
_counter++;
});
}
@override
Widget build(BuildContext context) { // 组件的方法,在这里返回的即为 _MyHomePageState 组件的布局。
return Scaffold( // Scaffold 实现了 Material Design 的基本布局结构,例如 AppBar、Drawer、SnackBar 等,它经常会作为 MaterialApp 的子Widget,Scaffold 会自动填充可用的空间,这通常意味着它将占据整个窗口或屏幕,并且 Scaffold 会自动适配不同的屏幕。
appBar: AppBar( //标题 bar
title: Text(widget.title),
),
body: Center( // 页面内容
child: Column( //布局方式,垂直线性排列
mainAxisAlignment: MainAxisAlignment.center, // 对齐方式:居中对齐
children: <Widget>[ // children:子组件数组,可以看到,下面往这个数组中放置了两个 Text()。
Text( // 这里就是页面中看到的 “You have pushed the button this many times:” 文字的组件。
'You have pushed the button this many times:',
),
Text( //点击后更改的数字值就是这个 Text
'$_counter', // _counter 是前边定义的变量,这是引用的方法。
style: Theme.of(context).textTheme.headline4, // 样式
),
],
),
),
floatingActionButton: FloatingActionButton( // 页面中右下角圆形悬浮按钮 FAB。
onPressed: _incrementCounter,
// onPressed 点击事件:调用了上边定义的 _incrementCounter()方法,
//在这个方法中实现了 _counter++,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
这里便是实现计时器最关键的部分。各个部分的说明也写在了上面的注释中。
结束
由此可以看到 Flutter 的页面是由一个个的组件嵌套而成,不少人会害怕嵌套地狱,其实根本没啥事,你看这个 Demo 中的包含关系不就是:
MyApp ⊃ MyHomePage(_MyHomePageState) ⊃ Scaffold ⊃ AppBar & Center & FloatingActionButton
Center ⊃ Column ⊃ Text & Text ⊃
但是可以封装出来,用自定义组件继承,这样代码中就不会出现嵌套地狱,而且新的组件可以新建文件来写,只要注意导包(路径),整体代码可读性很高,而且可以封装的很简洁,反而脉络更加清晰。
欢迎大家留言或者发邮件给我:
邮箱:ymwmlxl@gmail.com
网友评论