Flutter 高效自学笔记(二)

Flutter 高效自学笔记(一)网络

这是上篇文章文末提到的「第三个教程」的快速自学笔记。app

Widget 部件

读音 /'wɪdʒɪt/ 危机特,文档说借鉴了 React。我认为 Widget 至关于 React 里的组件 Component。less

下文将 Widget 所有称为「部件」。ide

部件的特色函数

  1. 基于你传给它配置和 state 生成视图
  2. 当一个部件的 state 变化了,部件就会更新视图
  3. Flutter 会对比新旧视图的区别,对实际视图作最小化的变更

runApp

这是 Flutter 应用必须调用的 API,接受一个部件。我的认为这很像是 React 的 ReactDOM.render 操做。布局

import 'package:flutter/material.dart';

void main() {
  runApp(
    Center(
      child: Text(
        'Hello, world!',
        textDirection: TextDirection.ltr,
      ),
    ),
  );
}
复制代码

以上代码的做用:post

  1. Center 是个类,Center() 就是实例化出一个实例
    1. 我很是欣赏删掉 new 的作法,不再会有人问 Center() 和 new Center() 的区别了,fuck JS。
  2. Center(...) 返回一个部件,做为根部件
  3. Center(...) 部件的子部件是 Text(...),若是只有一个子组件就用 child,若是有多个子组件就用 children
  4. Flutter 会强行让根部件占满屏幕(好评),因此最终效果就是屏幕中央有个 Hello, world! 字符串
  5. 代码中须要用 textDirection 指明文字方向,你用 MaterialApp 就能够省掉这一步,后面会讲
  6. 全部的部件类要么是 StatelessWidget 的子类,要么是 StatefulWidget 的子类
  7. 一个部件的主要功能是提供 build 方法(我的认为相似于 React 的 render),build 方法能够调用更多其余部件
  8. Flutter 会遍历这些子部件,而后计算出当前部件的结构

基础部件

经常使用的部件有:flex

  • Text:顾名思义
  • Row 和 Column:布局用的,相似于 CSS 的 flex 布局
  • Stack:布局用的,相似于 CSS 的绝对布局
  • Container:通用布局,相似于 div

MaterialApp

若是你想用一些 Material 风格的部件,只须要作这几件事就能够:动画

  1. 在 pubspec.yml 里添加以下代码ui

    flutter:
         uses-material-design: true
    复制代码
  2. runApp 的时候使用 MaterialApp,并使用 Material 部件

    runApp(MaterialApp(
         title: 'My app', // used by the OS task switcher
         home: Material(),
     ));
    复制代码
  3. import 'package:flutter/material.dart';

经常使用的 Material 部件

  1. Navigator:相似于 ReactRouter

  2. AppBar:顶部的 bar

    AppBar(
         leading: IconButton(
             icon: Icon(Icons.menu),
             tooltip: 'Navigation menu',
             onPressed: null,
         ),
         title: Text('Example title'),
         actions: <Widget>[
             IconButton(
             icon: Icon(Icons.search),
             tooltip: 'Search',
             onPressed: null,
             ),
         ],
     )
    复制代码
  3. Scaffold: 最经常使用的布局部件

    Scaffold(
       appBar: AppBar(...),
       body: Center(...),
       floatingActionButton: ...
     );
    复制代码

这些传参方式很像 Vue 的命名插槽。

用 GestureDetector 处理用户交互

这是一个自定义 button 部件:

class MyButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(               // <-- 注意看这里
      onTap: () {
        print('MyButton was tapped!');
      },
      child: Container(
        height: 36.0,
        padding: ...,
        margin: ...,
        decoration: ...,
        child: Center(
          child: Text('Engage'),
        ),
      ),
    );
  }
}
复制代码
  1. GestureDetector 部件并无任何表现层,只处理用户交互。当用户点击 Container 部件时,会触发 GestureDetector 部件的 onTap 回调。
  2. GestureDetector 支持的交互至关多,如轻触、拖曳和缩放。
  3. 不少其余部件都借助 GestureDetector 来接收回调,如 IconButton, RaisedButton 和 FloatingActionButton 都接收 onPressed 回调。

改变 state

无状态部件从父级接收数据,并把数据存在本身的 final 成员变量里(相似于 JS 的 const)。

有状态的部件则知道如何建立 state 对象,并维持 state 对象。

如何使用呢?

首先声明一个 StatefulWidget

class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}
复制代码

这个部件须要重写 createState 方法,而这个方法的返回值的类型,必须继承自 State 类。

_CounterState 是如何继承 State 的呢

class _CounterState extends State<Counter> {
  int _counter = 0;

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

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        RaisedButton(
          onPressed: _increment,
          child: Text('Increment'),
        ),
        Text('Count: $_counter'),
      ],
    );
  }
}
复制代码
  1. 须要重写 build 方法提供视图,并且可使用 '$_counter' 混入语法
  2. 在按钮被点击的时候调用 _increment,这个 _increment 会调用 State 提供的 setState 函数,给 setState 函数传入一个函数,这个传入的函数能够对数据进行修改。
  3. 很是像 React 的 Class 组件。区别在于
    1. Flutter 的部件和 state 是分开的类,而 React 只是把 state 用一个 hash 表示。
    2. Flutter 的 State 里面提供 build 方法,而 React 的 state 只是一个 hash
    3. Flutter 将 StatelessWidget 和 StatefulWidget 分开,能更好地组织代码

生命周期

StatefulWidget 有 createState 方法,State 有 initState 方法。

Flutter 调用 createState 方法后,获得一个 State 对象,而后调用这个 State 对象的 initState 方法。

你的自定义 State 类能够重写 initState 方法,这个方法只会调用一次。好比你能够重写 initState 来配置动画或者订阅事件。

当一个 State 对象快死的时候,Flutter 会调用 State 对象的 dispose 方法。你也能够重写 dispose 方法,好比在里面取消 timer 或者取消订阅。

keys

Flutter 默认是经过部件的 runtimeType 和出现顺序来肯定一个部件的身份的,这样才能在对比新旧部件树的过程当中肯定哪一个是哪一个。若是你给部件赋予了 key,那么就不用根据「出现顺序」来惟一肯定组件了,由于这种方式不太靠谱。

我的认为跟 React 的 key 有相同的做用。

key 分为兄弟间的 key 和全局 key。目前还不知道应用场景的区别。大部分时候应该只须要用兄弟间的 key 用来区分兄弟就好了。


下一篇文章打算看看 Flutter 如何发起网络请求。

未完待续……

相关文章
相关标签/搜索