基本知识
基本知识
如何创建一个 Flutter 应用?
如果要使用 React Native 创建应用,你需要在命令行里运行 create-react-native-app。
$ create-react-native-app <projectname>
要在 Flutter 中创建应用,完成下面其中一项即可:
-
使用带有 Flutter 和 Dart 插件的 IDE。
-
在命令行中运行命令
flutter create。不过要提前确认 Flutter SDK 已经在系统环境变量 PATH 中定义。
$ flutter create <projectname>
如果想要了解更多内容,详见 开始使用 Flutter,在该页面会手把手教你创建一个点击按钮进行计数的应用。创建一个 Flutter 项目就可以构建 Android 和 iOS 设备上运行应用所需的所有文件。
我如何运行应用呢?
在 React Native, 你可以在项目文件夹中运行 npm run 或者 yarn run。
你可以通过如下几个途径运行 Flutter 应用程序:
-
在带有 Flutter 和 Dart 插件的 IDE 中使用 “run” 选项。
-
在项目根目录运行
flutter run。
你的应用程序会在已连接的设备、iOS 模拟器或者 Android 模拟器上运行。
如果想了解更多相关信息,可以参考 Flutter 的相关文档:开始使用 Flutter。
如何导入 widget
在 React Native 中,你需要导入每一个所需的组件。
//React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
在 Flutter 中,如果要使用 Material Design 库里的 widget,导入 material.dart 包。如果要使用 iOS 风格的 widget,导入 Cupertino 库。如果要使用更加基本的 widget,导入 Widget 库。或者,你可以实现自己的 widget 库并导入。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/my_widgets.dart';
无论你导入哪个库,Dart 仅仅引用你应用中用到的 widget。
如果想了解更多相关信息,可以参考 核心 Widget 目录。
在 Flutter 里有没有类似 React Native 中 “Hello world!” 应用程序?
在 React Native,HelloWorldApp 继承自 React.Component 并且通过返回 view 对象实现了 render 方法。
// React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Hello world!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
});
在 Flutter 中,你可以使用核心 widget 库中的 Center 和 Text widget 创建对应的 “Hello world!” 应用程序。Center widget 是 widget 树中的根,而且只有 Text 一个子 widget。
// Flutter
import 'package:flutter/material.dart';
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
下面的图片展示了 Android 和 iOS 中的基本 Flutter “Hello world!” 应用程序的界面。
Android
iOS
现在大家已经明白了最基本的 Flutter 应用,接下来会告诉大家如何利用 Flutter 丰富的 widget 库来创建主流的华丽的应用程序。
我如何使用 widget 并且把它们封装起来组成一个 widget 树?
在 Flutter 中,几乎任何元素都是 widget。
widget 是构建应用软件用户界面的基本元素。你可以将 widget 按照一定的层次组合,成为 widget 树。每个 widget 内嵌在父 widget 中,并且继承了父 widget 的属性。甚至应用程序本身就是一个 widget。并没有一个独立的应用程序对象。反而 root widget 充当了这个角色。
一个 widget 可以定义:
-
一个结构化的元素 - 类似按钮或者菜单
-
一个风格化的元素 - 类似字体或者颜色方案
-
布局元素 - 类似填充区或者对齐元素
下面的示例展示了使用 Material 库里 widget 实现的 “Hello world!” 应用程序。在这个示例中,该 widget 树是包含在 MaterialApp root widget 里的。
// Flutter
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Hello world'),
),
),
);
}
}
下面的图片为大家展示了通过 Material Design widget 所实现的 “Hello world!” 应用。你可以获得比 “Hello world!” 应用更多的功能。
Android
iOS
当编写应用代码的时候,你将用到下述两种 widget :
无状态 widget (StatelessWidget) 就像它的名字一样,是一个没有状态的 widget。无状态 widget 一旦创建,就不会改变。而有状态 widget (StatefulWidget)会基于接收到的数据或者用户输入的数据动态改变状态。
无状态 widget 和有状态 widget 之间的主要区别是有状态 widget 包含一个 State 对象,会缓存状态数据,并且 widget 树的重构也会携带该数据,因此状态不会丢失。
在简单的或者基本的应用程序中,封装 widget 非常简单,但是随着代码量的增加并且应用程序的功能变得更加复杂,你应该将层级复杂的 widget 封装到函数中或者稍小一些的类。创建独立的函数和 widget 可以让你更好地复用应用中组件。
如何创建可复用的组件?
在 React Native 中,你可以定义一个类来创建一个可复用的组件然后使用 props 方法来设置或者返回属性或者所选元素的值。在下面的示例中,CustomCard 类在父类中被定义和调用。
// React Native
class CustomCard extends React.Component {
render() {
return (
<View>
<Text> Card {this.props.index} </Text>
<Button
title="Press"
onPress={() => this.props.onPress(this.props.index)}
/>
</View>
);
}
}
// Usage
<CustomCard onPress={this.onPress} index={item.key} />
在 Flutter 中,定义一个类来创建一个自定义 widget 然后复用这个 widget。你可以定义并且调用函数来返回一个可复用的 widget,正如下面示例中 build 函数所示的那样。
// Flutter
class CustomCard extends StatelessWidget {
CustomCard({@required this.index, @required
this.onPress});
final index;
final Function onPress;
@override
widget build(BuildContext context) {
return Card(
child: Column(
children: <Widget>[
Text('Card $index'),
FlatButton(
child: const Text('Press'),
onPressed: this.onPress,
),
],
)
);
}
}
...
// Usage
CustomCard(
index: index,
onPress: () {
print('Card $index');
},
)
...
在之前的示例,CustomCard 类的构造函数使用 Dart 的曲括号 { } 来表示可选参数 optionalparameters。
如果将这些参数设定为必填参数,要么从构造函数中删掉曲括号,或者在构造函数中加上 @required。
下面的截图展示了可复用的 CustomCard 类的示例。
Android
iOS
