从 flutter demo走进flutter 世界

402 阅读3分钟

工程结构

打开Android studio 创建一个flutter 项目,会默认创建一个计数器项目。在右边project 下,可以看到:

image.png 分析一下几个重要的文件目录和文件:

android:包含Android的特定文件和Android子工程
build:Android 和iOS 的构建产物
ios:包含iOS 的特定文件和iOS 子工程
lib:放置flutter 代码
    main.dart:程序的入口文件,类似Android 的application
test:测试文件
flutter_app.iml:工程配置文件
pubspec.lock:记录当前项目实际依赖信息的文件
pubspec.yaml:管理第三方库和资源文件

之所以有Android 和iOS 子项目,是因为flutter 最终会以原生的形式运行。

从简单的demo学习flutter项目的运行机制

在flutter 的世界中,一切都是widget,widget 是组件视觉效果的封装,是 UI 界面的载体,通过 build方法来构建UI页面。 看看main.dart 文件中的代码

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
  1. 从main函数开始,调用 runApp方法 传入MyApp(就是一个widget),APP就是我们看到的首页。
  2. 在 MyApp的build 方法中,返回了 MaterialApp(也是一个widget),里面还有很多可配置的属性,比如应用主题、应用名称、语言标识符、组件路由等。
  3. 在 MaterialApp,看到 MyHomePage(也是一个widget),但是这个 StatefulWidget 的子类,构建UI不是直接通过build 方法,而是交给 _MyHomePageState来完成。

到这来就可以看到,在flutter 中有两种 widget,StatelessWidget 和 StatefulWidget。

StatelessWidget:无状态的widget,UI构建的从一开始就是确定的,在 widget 的生命周期中不会发生变化。

StatefulWidget:有状态的widget,在widget 的生命周期中数据发生变化,在数据发生变化后,调用 setState方法来通知flutter 框架,重新创建widget。

随着数据的变化重新创建和销毁widget,会不会对性能有影响呢,flutter 如何优化的?

答案是:不会。因为框架内部会通过一个中间层去收敛上层 UI 配置对底层真实渲染的改动,从而最大程度降低对真实渲染视图的修改,提高渲染效率,而不是上层 UI 配置变了就需要销毁整个渲染视图树重建。

总结

从上面可以看出,在flutter 的世界里,widget 是无处不在,在页面上看到的一切的一切都是widget,如:AppBar、Center、Text、FloatingActionButton……都是widget,我们可以在widget构建的时候,做好配置,如,Text 文字大小、文字颜色、文字内容、点击事件等等,然后在数据发生变化后,通过调用 setState方法,就可以更新UI了。