基本知识

基本知识

如何创建一个 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!” 应用程序的界面。

Hello world app on Android Android

Hello world app on iOS 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!” 应用更多的功能。

Hello world app on Android Android

Hello world app on iOS 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 类的示例。

Custom cards on Android Android

Custom cards on iOS iOS