widget(widgets有什么用)
1 widget简介在 Flutter 一切的显示都是 Widget ,Widget 是一切的基础,利用响应式模式进行渲染。Flutter 从
1 widget简介在 Flutter 一切的显示都是 Widget ,Widget 是一切的基础,利用响应式模式进行渲染Flutter 从 React 中吸取灵感,通过现代化框架创建出精美的组件它的核心思想是用 widget 来构建你的 UI 界面。
Widget 描述了在当前的配置和状态下视图所应该呈现的样子当 widget 的状态改变时,它会重新构建其描述(展示的 UI),框架则会对比前后变化的不同,以确定底层渲染树从一个状态转换到下一个状态所需的最小更改。
2 hello world具体介绍前,先创建一个最小的 Flutter 应用voidmain() { runApp( Center( child: Text( Hello, world!
, textDirection: TextDirection.ltr, ), ), ); }runApp() 函数会持有传入的 Widget,并且使它成为 widget 树中的根节点。
在这个例子中,Widget 树有两个 widgets, Center widget 及其子 widget ——Text 框架会强制让根 widget 铺满整个屏幕,也就是说“Hello World”会在屏幕上居中显示。
在这个例子我们需要指定文字的方向,当使用 MaterialApp widget 时,你就无需考虑这一点,之后我们会进一步的描述Widget 分为 有状态 和 无状态 两种,在 Flutter 中每个页面都是一帧,无状态就是保持在那一帧,而有状态的 Widget 当数据更新时,其实是创建了新的 Widget,只是 State 实现了跨帧的数据同步保存。
在写应用的过程中,取决于是否需要管理状态,你通常会创建一个新的组件继承 StatelessWidget 或 StatefulWidgetWidget 主要工作是实现 build方法,该方法是根据其它较低级别的 widget 来描述这个 widget。
框架会逐一构建这些 widget,直到最底层的描述 widget 几何形状的 RenderObject我们先来看一下Widget类的声明:@immutableabstractclassWidgetextends
DiagnosticableTree{ constWidget({ this.key }); final Key key; @protectedElement createElement()
; @overrideString toStringShort(){ return key == null ? $runtimeType : $runtimeType-$key; }
@overridevoiddebugFillProperties(DiagnosticPropertiesBuilder properties){ super.debugFillProperties(properties); properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense; }
static bool canUpdate(Widget oldWidget, Widget newWidget){ return oldWidget.runtimeType == newWidget.runtimeType && oldWidget.key == newWidget.key; } }
Widget类继承自DiagnosticableTree,DiagnosticableTree即“诊断树”,主要作用是提供调试信息Key: 这个key属性类似于React/Vue中的key,主要的作用是决定是否在下一次。
build时复用旧的widget,决定的条件在canUpdate()方法中createElement():正如前文所述“一个Widget可以对应多个Element”;Flutter Framework在构建UI树时,会先调用此方法生成对应节点的。
Element对象此方法是Flutter Framework隐式调用的,在我们开发过程中基本不会调用到debugFillProperties(...) 复写父类的方法,主要是设置诊断树的一些特性canUpdate(...)
是一个静态方法,它主要用于在Widget树重新build时复用旧的widget,其实具体来说,应该是:是否用新的Widget对象去更新旧UI树上所对应的Element对象的配置;通过其源码我们可以看到,只要
newWidget与oldWidget的runtimeType和key同时相等时就会用newWidget去更新Element对象的配置,否则就会创建新的Element另外Widget类本身是一个抽象类,其中最核心的就是定义了。
createElement()接口,在Flutter开发中,我们一般都不用直接继承Widget类来实现一个新组件,相反,我们通常会通过继承StatelessWidget或StatefulWidget来间接继承
Widget类来实现StatelessWidget和StatefulWidget都是直接继承自Widget类,而这两个类也正是Flutter中非常重要的两个抽象类,它们引入了两种Widget模型,接下来我们将重点介绍一下这两个类。
3 无状态StatelessWidgetStatelessWidget相对比较简单,它继承自Widget类,重写了createElement() 方法:@override StatelessElement
createElement()=> new StatelessElement(this)StatelessElement 间接继承自Element类,与StatelessWidget相对应(作为其配置数据)。
StatelessWidget用于不需要维护状态的场景,它通常在build方法中通过嵌套其它Widget来构建UI如下下代码所示是无状态 Widget 的简单实现继承 StatelessWidget,通过 build 方法返回一个布局好的控件。
可能现在你还对 Flutter 的内置控件不熟悉,but Dont worry , take it easy ,后面我们就会详细介绍这里你只需要知道,一个无状态的 Widget 就是这么简单Widget 和 Widget 之间通过 。
child: 进行嵌套其中有的 Widget 只能有一个 child,比如下方的 Container ;有的 Widget 可以多个 child ,也就是children,比如` Column 布局,下方代码便是 Container Widget 嵌套了 Text Widget。
importpackage:flutter/material.dart; classDEMOWidgetextendsStatelessWidget{ final String text; DEMOWidget(
this.text); @overrideWidget build(BuildContext context){ return Container( color: Colors.white, child: Text(text ??
"这就是无状态DMEO"), ); } }build方法有一个context参数,它是BuildContext类的一个实例,表示当前widget在widget树中的上下文,每一个widget都会对应一个context对象(因为每一个widget都是widget树上的一个节点)。
实际上,context是当前widget在widget树中位置中执行”相关操作“的一个句柄,比如它提供了从当前widget开始向上遍历widget树以及按照widget类型查找父级widget的方法4 有状态StatefulWidget
StatefulWidget和StatelessWidget一样,StatefulWidget也是继承自Widget类,并重写了createElement() 方法,不同的是返回的Element 对象并不相同;另外
StatefulWidget类中添加了一个新的接口createState()StatefulWidget的类定义如下:abstractclassStatefulWidgetextendsWidget{
constStatefulWidget({ Key key }) : super(key: key); @overrideStatefulElement createElement()=> new StatefulElement(
this); @protectedState createState(); }StatefulElement 间接继承自Element类,与StatefulWidget相对应(作为其配置数据)StatefulElement 。
中可能会多次调用createState()来创建状态(State)对象createState() 用于创建和Stateful widget相关的状态,它在Stateful widget的生命周期中可能会被多次调用。
例如,当一个Stateful widget同时插入到widget树的多个位置时,Flutter framework就会调用该方法为每一个位置生成一个独立的State实例,其实,本质上就是一个StatefulElement
对应一个State实例。flutter生命周期请主页《Flutter生命周期以及使用》;
免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186