简介
Flutter作为跨平台的语言越来越被重视,特别是近两年许多互联网公司都在降本增效的时候,学会Flutter开发就变得十分重要了,有助于在日常工作中不被淘汰。
在Java中,万事万物皆为对象。同样在Flutter中,几乎所有的对象都是一个Widget。和其他开发语言不同的是,Flutter中的widget表示的含义更广泛,UI元素,View组件,主题,手势事件等都是一个Widget。
分类
Flutter中的Widget主要分为两类StatelessWidget和StatefulWidget。
StatelessWidget表示无状态的Widget。
StatefulWidget表示有状态的Widget。
区别
下面分别从代码结构,使用场景来区分两种Widget的不同.
代码结构
StatelessWidget
从源码可以看出StatelessWidget是一个抽象类继承自Widget,内部默认实现创建了一个StatelessElement 对象和build方法。StatelessElement内部也只有一个update方法用来构建页面。
StatefulWidget
abstract class StatefulWidget extends Widget { /// Initializes [key] for subclasses. const StatefulWidget({ super.key }); @override StatefulElement createElement() => StatefulElement(this); /// [State] objects. @protected @factory State createState(); } class StatefulElement extends ComponentElement { ................. @override Widget build() => state.build(this); State<StatefulWidget> get state => _state!; State<StatefulWidget>? _state; ............... @override void update(StatefulWidget newWidget) { super.update(newWidget); assert(widget == newWidget); final StatefulWidget oldWidget = state._widget!; state._widget = widget as StatefulWidget; .............. return true; }()); rebuild(force: true); } @override void activate() { super.activate(); state.activate(); assert(_lifecycleState == _ElementLifecycle.active); // otherwise markNeedsBuild is a no-op markNeedsBuild(); } @override void deactivate() { state.deactivate(); super.deactivate(); } @override void unmount() { super.unmount(); state.dispose(); state._element = null; _state = null; } @override InheritedWidget dependOnInheritedElement(Element ancestor, { Object? aspect }) { assert(ancestor != null); ..... return super.dependOnInheritedElement(ancestor as InheritedElement, aspect: aspect); } bool _didChangeDependencies = false; @override void didChangeDependencies() { super.didChangeDependencies(); _didChangeDependencies = true; } @override DiagnosticsNode toDiagnosticsNode({ String? name, DiagnosticsTreeStyle? style }) { return _ElementDiagnosticableTreeNode( name: name, value: this, style: style, stateful: true, ); } @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties.add(DiagnosticsProperty<State<StatefulWidget>> ('state', _state, defaultValue: null)); } }
StatefulWidget内部StatefulElement 中不仅有update()方法还有activate,deactivate,didChangeDependencies等方法。具体方法使用以后慢慢讲解。
使用场景
1 StatelessWidget
StatelessWidget从字面意思就可以看出是无状态的Widget。这里的无状态通俗来说,一旦控件确定,就不能改变其状态。包括显示状态,点击状态等。通常用来表示一些不涉及到页面变化,更新等控件。
示例:
这里封装了一个CommonButton按钮,按钮的构造函数中只传入了text文本和点击事件的回调。也就是说一旦传入了text,按钮本身的显示状态并不会发生改变,而且点击事件也是由调用者来实现,对应按钮本身来说不会发生任何改变。
2 StatefulWidget
StatefulWidget表示有状态的widget,或者是说有生命周期的Widget,这里的状态同样是指widget本身的状态,如形状,角度,颜色,背景色等发生改变。
示例:
同样还是CommonButton,这次继承自StatefulWidget,给按钮添加了一个旋转动画,在initState方法中初始化动画控制器,在dispose方法中解绑控制器,由于是给按钮本身添加了动画,当点击按钮时,按钮自身状态发生了改变。所以必须要用StatefulWidget,如果用StatelessWidget是无法实现按钮自身的旋转的。读者可以动手试试。
总结
在Flutter中,不论是StatelessWidget还是StatefulWidget都是经常使用的控件,熟练掌握Widget的基本使用场景有效提高开发效率,特别是正确区分不同Widget的使用场景,本文从简单的Widget开始介绍StatelessWidget和StatefulWidget和区别和使用场景。
发表评论 取消回复