2019-06-01 27 Flutter
Widget
- runApp函数接受- Widget, 并使其成为Widget的根
  void main() {
    runApp(
      ...
    );
  }
- 
    StatelessWidget, 例如Icon、Text等无状态Widget, 需要复写Widget#build()函数
- 
    StatefulWidget, 与用户交互或随时间变化, 当Widget改变时, 调用setState()通知框架重绘widget, 自定义StatefulWidget需要创建StatefulWidget和State类
  // 实例,
  class FavoriteWidget extends StatefulWidget {
      @override
      createState() => new _FavoriteWidgetState();
  }
  class _FavoriteWidgetState extends State<FavoriteWidget> {
    ...
    void _toggleFavorite() {
      // 通知刷新
      setState(() {
        if (_isFavorite) {
          _isFavorite = false;
          _favoriteCount -= 1;
        } else {
          _favoriteCount += 1;
          _isFavorite = true;
        }
      });
    }
    @override
    Widget build(BuildContext context) {
      // TODO: implement build
      return new Row(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          new Container(
            padding: new EdgeInsets.all(0.0),
            child: new IconButton(
                icon: _isFavorite
                    ? new Icon(Icons.star)
                    : new Icon(Icons.star_border),
                color: Colors.red[500],
                onPressed: _toggleFavorite),
          ),
          new SizedBox(
            width: 18.0,
            child: new Container(
              child: new Text('$_favoriteCount'),
            ),
          ),
        ],
      );
    }
  }
- 管理状态
    - Widget管理自己的状态, 在手势(事件响应)中,- Widget在类中响应(- setState())刷新UI
- 父Widget管理Widget状态, 在手势(事件响应)中, 需要父Widget更新, 则把状态由父Widget管理, 子Widget把事件回调给父Widget
- 混搭管理, 父Widget和子Widget共同响应刷新UI
 
布局
- 行(Row)水平排布, 列(Column)垂直排布, 包含mainAxisAlignment主轴和crossAxisAligment交叉轴对齐属性, 类似Android的LinearLayout
- 
    ExpandWidget控制沿主轴方向的widget大小, 通过调整ExpandWidget#flex属性,默认是1, 类似CSS的flex
- 拥有单子元素的布局widget
    - Container, 绘制、定位、调整大小- Container( constraints: BoxConstraints.expand( height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0, ), padding: const EdgeInsets.all(8.0), color: Colors.blue[600], alignment: Alignment.center, child: Text('Hello World', style: Theme.of(context) .textTheme .display1 .copyWith(color: Colors.white)), transform: Matrix4.rotationZ(0.1), )
- Padding, 给子widget添加指定填充- Padding( padding: EdgeInsets.all(8.0), child: const Card(child: Text('Hello World!')), )
- Center, 将子widget居中显示
- Align, 将子widget对齐
 
    Align(
      alignment: Alignment(0.2, 0.6),
      child: FlutterLogo(
        size: 60,
      )
    )
- ConstrainedBox约束布局- ConstrainedBox( constraints: const BoxConstraints.expand(), child: const Card(child: Text('Hello World!')), )
- 多个子元素的布局
    - 常用的如Row,Column
- Stack允许子widget堆叠- Stack( children: <Widget>[ Container( width: 100, height: 100, color: Colors.red, ), Container( width: 90, height: 90, color: Colors.green, ), ... ], )
- ListView, 滚动列表布局- ListView( padding: const EdgeInsets.all(8.0), children: <Widget>[ Container( height: 50, color: Colors.amber[600], child: const Center(child: Text('Entry A')), ), Container( height: 50, color: Colors.amber[500], child: const Center(child: Text('Entry B')), ), ... ], )
 
- 常用的如
手势
- Pointers, 表示touch, stylus, 或者mouse事件- PointerDownEvent, The pointer has made contact with the device.
- PointerMoveEvent, The pointer has moved with respect to the device while the pointer is in contact with the device.
- PointerUpEvent, The pointer has stopped making contact with the device.
- PointerCancelEvent, The input from the pointer is no longer directed towards this receiver.
 
- GestureDetector, 拦截事件的widget
  GestureDetector(
    onTap: () {
      setState(() { _lights = true; });
    },
    child: Container(
      color: Colors.yellow,
      child: Text('TURN LIGHTS ON'),
    ),
  )
动画
- 补间(Tween)动画
- 基于物理的动画
Http网络请求
  import 'dart:convert';
  import 'dart:io';
  _getIPAddress() async {
    var url = 'https://httpbin.org/ip';
    var httpClient = new HttpClient();
    var request = await httpClient.getUrl(Uri.parse(url));
    var response = await request.close();
    if (response.statusCode == HttpStatus.OK) {
      var json = await response.transform(utf8.decoder).join();
      var data = jsonDecode(json);
      String result = data['origin'];
    }
    ...
  }
 
      
    
