Flutter Widget框架概述

介绍

Flutter Widget采用现代响应式框架构建,中心思想是用widget构建你的UI。Widget描述了他们的视图在给定其当前配置和状态时看起来像什么。当widget的状态发生变化时,widget会重新构建UI,Flutter会对比前后变化的不同,以确定底层渲染树从一个状态转换到下一个状态所需的最小更改。

基础Widget

Flutter有一套丰富的基础widget。

  • Text:该widget可以创建一个带格式的文本
  • Row、Column:这些具有弹性空间的布局类Widget可以在水平、垂直方向上创建灵活的布局
  • Stack:取代线性布局,Stack允许子widget堆叠,可以使用Positioned来定位他们相对于Stack的上下左右四条边的位置
  • Container:可以创建矩形视觉元素,container可以装饰为一个BoxDecoration,如background、一个边框或者一个阴影。Container也可以具有边距、填充和应用于其大小的约束,另外,Container可以使用矩阵在三维空间中对其进行变换

下面是一个简单的代码示例

void main() => runApp(new MaterialApp(title: 'My App', home: new MyScaffold()));

class MyAppBar extends StatelessWidget {
  final Widget title;

  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 56.0,
      padding: const EdgeInsets.symmetric(horizontal: 8.0),
      decoration: new BoxDecoration(color: Colors.blue[500]),
      child: new Row(
        children: <Widget>[
          new IconButton(
              icon: new Icon(Icons.menu),
              tooltip: "Navigation menu",
              onPressed: null),
          new Expanded(child: title),
          new IconButton(
              icon: new Icon(Icons.search), tooltip: "Search", onPressed: null)
        ],
      ),
    );
  }

  MyAppBar({this.title});
}

class MyScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Material(
      child: new Column(
        children: <Widget>[
          new MyAppBar(
              title: new Text(
            "Expanded Title",
            style: Theme.of(context).primaryTextTheme.title,
          )),
          new Expanded(
              child: new Center(
            child: new Text("Hello Flutter"),
          ))
        ],
      ),
    );
  }
}

Material组件

Flutter提供了许多widgets,可以构建遵循Material Design的应用程序。Material应用程序已MaterialApp widget开始,该weiget在应用程序的根部创建了一些有用的widget,包括一个Navigator,它管理由字符串便是的Widget栈,Navigator可以让应用程序在页面之间平滑的过渡。

以下为简单floatingBar的代码示例

class TutorialHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        leading: new IconButton(
            icon: new Icon(Icons.menu),
            tooltip: "Navigation menu",
            onPressed: null),
        title: new Text("Example title"),
        actions: <Widget>[
          new IconButton(
              icon: new Icon(Icons.search), tooltip: "Search", onPressed: null)
        ],
      ),
      body: new Center(
        child: new Text("Hello world"),
      ),
      floatingActionButton: new FloatingActionButton(
          tooltip: "Add", child: new Icon(Icons.add), onPressed: null),
    );
  }
}

处理手势

class MyButton extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: (){
        print("button was tapped");
      },
      child: new Container(
        height: 36.0,
        padding: const EdgeInsets.all(8.0),
        decoration: new BoxDecoration(
          borderRadius: new BorderRadius.circular(5.0),
          color: Colors.lightGreen[500],
        ),
        child: new Center(
          child: new Text("Engage"),
        ),
      ),
    );
  }
}

当用户点击Container时,GestureDetector会调用它的onTap回调,同样也可以在GestureDetector中监测各种手势

根据用户输入改变widget

上面使用的widget是无状态的widget,无状态widget从他们的父widget接收参数,他们被存储在final型的成员变量中,当一个widget被要求构建时,它使用这些存储的值作为参数来构建widget

为了构建更复杂的体验,Flutter会使用StatefulWidget来满足这种需求。StatefulWidget是特殊的widget,它知道如何生成State对象,然后用它来保持状态。

class Counter extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new CounterState();
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new RaisedButton(
          onPressed: increment,
          child: new Text("Increment"),
        ),
        new Text("Count:$_counter"),
      ],
    );
  }
}

StatefulWidget和State是单独的对象,在Flutter中,这两种类型的对象有不同的生命周期:Widget是临时对象,用于构建当前状态下的应用程序,而State独享在多次调用build之间保持不变,允许他们记住信息

在Flutter中,事件流是向上传递的,而状态流是向下传递的,子widget到父widget是通过事件传递的,而父到子是通过状态。重定向这一流程的共同父元素是State。

下面将逻辑分别封装在各个widget中,保持父项的简单性:

class CounterDisplay extends StatelessWidget {
  CounterDisplay({this.count});

  final int count;

  @override
  Widget build(BuildContext context) {
    return new Text("Count:$count");
  }
}

class CounterIncrementor extends StatelessWidget {
  CounterIncrementor({this.onPressed});

  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return new RaisedButton(
      onPressed: onPressed,
      child: new Text("Increment"),
    );
  }
}

class Counter extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new CounterState();
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new CounterIncrementor(onPressed: increment),
        new CounterDisplay(count: _counter)
      ],
    );
  }
}

响应widget生命周期事件

在StatefulWidget调用createState之后,框架将新的状态插入树种,然后调用状态对象的initState。子类化State可以重写initState,以完成仅需要一次执行的工作。当然在initState的实现中需要调用super.initState

当一个状态对象不再需要时,框架调用状态对象的dispose。也可以通过覆盖dispose方法来执行清理工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值