Flutter的Widget采用的是现代化的React风格,该风格的设计灵感来源于React这么语言。最核心的理念是你可以使用Widget设计界面。Widget通过当前的state和注册信息来描述view应该长成什么样子的。当当前的状态发生了变化后,Widget会重新构建。

一、Hello World

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

上面是一个简单的Widget。
这里,可以总结出如下几点:

  • runApp()方法制定了根Widget,其他的Widget都应该是该Widget的子Widget
  • 默认会强制根Widget是覆盖全屏幕的
    除此之外,还有:
  • 自己创建的Widget应该是StatefulWidget或者StatelessWidget的子类,到底是哪个的子类,取决于该Widget是否需要管理一些state

二、StatefulWidget和State

为什么要将Widget和State分别写到两个类里呢?
上一节最后说到,我们将状态管理放到Widget里,是有问题的,有什么问题呢?这里在Widget和State里分别添加一个num属性,我每点击一次,对两个的num都加1,代码如下:

class _ParentWidget extends StatefulWidget {
bool active = false;
var num = 0;
@override
State<StatefulWidget> createState() => new _ParentWidgetState();
} class _ParentWidgetState extends State<_ParentWidget> { void _handleTapboxChanged(bool newValue) {
setState(() {
widget.active = newValue;
});
} @override
Widget build(BuildContext context) {
print("Parent State:${widget.num}");
widget.num += 1;
// TODO: implement build
return new Container(
child: new TapboxC(onChanged: _handleTapboxChanged, active: widget.active),
);
}
} typedef void changedValue(bool newValue); class TapboxC extends StatefulWidget {
var num = 0;
final bool _active;
bool _highlight = false;
changedValue changed;
// final ValueChanged<bool> onChanged;
TapboxC({Key key, bool active, @required changedValue onChanged})
:this._active = active, this.changed = onChanged, super(key: key) { }
@override
State<StatefulWidget> createState() {
print("TapBoxC createState");
return new _TapboxCState();
}
} class _TapboxCState extends State<TapboxC> {
var num = 0;
void _handleTap() {
widget.changed(!widget._active);
} void _handleTapDown(TapDownDetails details) {
setState((){
widget._highlight = true;
});
} void _handleTapUp(TapUpDetails details) {
setState((){
widget._highlight = false;
});
} void _handleTapCancel(){
setState((){
widget._highlight = false;
});
} @override
Widget build(BuildContext context) {
print("_TapboxCState build:${widget.num}, this num:$num");
num += 1;
widget.num += 1;
// TODO: implement build
return new GestureDetector(
onTap: _handleTap,
onTapDown: _handleTapDown,
onTapUp: _handleTapUp,
onTapCancel: _handleTapCancel,
child: new Container(
width: 200.0,
height: 200.0,
decoration: new BoxDecoration(
color: widget._active ? Colors.lightGreen[700] : Colors.grey[600],
border: widget._highlight
? new Border.all(color: Colors.teal[700], width: 10.0)
: null,
),
),
);
}
}

最后的结果如下:

image.png

你会发现,TapboxC的num一直在0和1之间跳动,而ParentWidget和TapboxCState的num都是递增的。这是为什么呢?
首先明确的是,每次回调改变ParentWidget的State时,都会重新初始化一次TapboxC,所以它的num每次都会变为0就不奇怪了,而因为ParentWidget并没有改变,所以会递增。
可能又有疑惑,那么为什么TabboxCState的num就不归0呢?
其实这都是和Widget和State 的生命周期有关。Widget相当于时一个暂时的对象,只是为了展示和布局当前状态时用的,一旦状态发生了改变,它就会失效;而State从某种角度来说是个永久对象,它里面存储了一些必要信息,这其实也是React的一个特性,即每次通过比较,只更新和修改差异化的东西。

Flutter学习笔记(四)--Flutter几个小知识点的更多相关文章

  1. Flutter学习笔记(8)--Dart面向对象

    如需转载,请注明出处:Flutter学习笔记(7)--Dart异常处理 Dart作为高级语言,支持面向对象的很多特性,并且支持基于mixin的继承方式,基于mixin的继承方式是指:一个类可以继承自多 ...

  2. Flutter学习笔记(1)--环境安装

    flutter最近显得格外的火,公司的同事也一直在谈论flutter,感觉自己不学学就要失业了...所以决定顺应潮流学习以下flutter,做一下学习笔记,希望可以给需要的同学带来一些帮助~ 正文为f ...

  3. Flutter学习笔记(4)--Dart函数

    如需转载,请注明出处:Flutter学习笔记(4)--Dart函数 Dart是一个面向对象的语言,所以函数也是对象,函数属于Function对象,函数可以像参数一样传递给其他函数,这样便于做回调处理: ...

  4. Flutter学习笔记(5)--Dart运算符

    如需转载,请注明出处:Flutter学习笔记(5)--Dart运算符 先给出一个Dart运算符表,接下来在逐个解释和使用.如下:                            描述       ...

  5. Flutter学习笔记(10)--容器组件、图片组件

    如需转载,请注明出处:Flutter学习笔记(10)--容器组件.图片组件 上一篇Flutter学习笔记(9)--组件Widget我们说到了在Flutter中一个非常重要的理念"一切皆为组件 ...

  6. Flutter学习笔记(11)--文本组件、图标及按钮组件

    如需转载,请注明出处:Flutter学习笔记(10)--容器组件.图片组件 文本组件 文本组件(text)负责显示文本和定义显示样式,下表为text常见属性 Text组件属性及描述 属性名 类型 默认 ...

  7. Flutter学习笔记(12)--列表组件

    如需转载,请注明出处:Flutter学习笔记(12)--列表组件 在日常的产品项目需求中,经常会有列表展示类的需求,在Android中常用的做法是收集数据源,然后创建列表适配器Adapter,将数据源 ...

  8. Flutter学习笔记(20)--FloatingActionButton、PopupMenuButton、SimpleDialog、AlertDialog、SnackBar

    如需转载,请注明出处:Flutter学习笔记(20)--FloatingActionButton.PopupMenuButton.SimpleDialog.AlertDialog.SnackBar F ...

  9. Flutter学习笔记(21)--TextField文本框组件和Card卡片组件

    如需转载,请注明出处:Flutter学习笔记(21)--TextField文本框组件和Card卡片组件 今天来学习下TextField文本框组件和Card卡片组件. 只要是应用程序就少不了交互,基本上 ...

  10. Flutter学习笔记(23)--多个子元素的布局Widget(Rwo、Column、Stack、IndexedStack、Table、Wrap)

    如需转载,请注明出处:Flutter学习笔记(23)--多个子元素的布局Widget(Rwo.Column.Stack.IndexedStack.Table.Wrap) 上一篇梳理了拥有单个子元素布局 ...

随机推荐

  1. VS2013发布网站详细步骤

    以下是我发布网站的时候,搜索到的可以使用的办法,同样适用于vs2013(已经尝试). 1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: V ...

  2. jquery控制css的display属性(显示与隐藏)

    jquery控制div的显示与隐藏,很方便的. 例如: $("#id").show()表示display:block, $("#id").hide()表示dis ...

  3. mysql参数配置文件

    (1)参数配置文件中的内容以键值对形式存在. (2)如何查看键值对?show variables like '%name%';或者查看information_schema库下的global_varia ...

  4. python性能分析(一)——使用timeit给你的程序打个表吧

    前言 我们可以通过查看程序核心算法的代码,得知核心算法的渐进上界或者下界,从而大概估计出程序在运行时的效率,但是这并不够直观,也不一定十分靠谱(在整体程序中仍有一些不可忽略的运行细节在估计时被忽略了) ...

  5. charles破解

    替换安装路径->Charles\lib下的charles.jar文件成破解版jar文件,如果再次启动未弹出30天试用的提示,说明破解成功 charles:https://pan.baidu.co ...

  6. python的os模块和sys模块

    os模块 os.getcwd()  获取当前的工作目录 os.chdir('绝对路径/相对于当前工作目录的路径')  改变工作目录,相当于shell的cd命令,例如Windows平台下os.chdir ...

  7. java反射field和method的顺序问题

    最近在有思考到序列化性能优化的问题,关于java反射field和method的顺序问题,这里有详细的讨论http://stackoverflow.com/questions/5001172/java- ...

  8. 04: python常用模块

    目录: 1.1 时间模块time() 与 datetime() 1.2 random()模块 1.3 os模块 1.4 sys模块 1.5 tarfile用于将文件夹归档成 .tar的文件 1.6 s ...

  9. Linux系统对IO端口和IO内存的管理

    引用:http://blog.csdn.net/ce123_zhouwei/article/details/7204458 一.I/O端口 端口(port)是接口电路中能被CPU直接访问的寄存器的地址 ...

  10. this逃逸

    首先,什么是this逃逸? this逃逸是指类构造函数在返回实例之前,线程便持有该对象的引用. 常发生于在构造函数中启动线程或注册监听器. eg: public class ThisEscape { ...