widget简介

分类: 365系统维护不给提款怎么办 时间: 2025-09-20 01:00:31 作者: admin 观测: 332
widget简介

2.1 widget简介

在 Flutter 中一切的显示都是 Widget ,Widget 是一切的基础,利用响应式模式进行渲染。Flutter 从 React 中吸取灵感,通过现代化框架创建出精美的组件。它的核心思想是用 widget 来构建你的 UI 界面。Widget 描述了在当前的配置和状态下视图所应该呈现的样子。当 widget 的状态改变时,它会重新构建其描述(展示的 UI),框架则会对比前后变化的不同,以确定底层渲染树从一个状态转换到下一个状态所需的最小更改。

2.1.1 hello world具体介绍前,先创建一个最小的 Flutter 应用

代码语言:javascript代码运行次数:0运行复制import 'package:flutter/material.dart';

void main() {

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 或 StatefulWidget。Widget 的主要工作是实现 build方法,该方法根据其它较低级别的 widget 来描述这个 widget。框架会逐一构建这些 widget,直到最底层的描述 widget 几何形状的 RenderObject。

我们先来看一下Widget类的声明:

代码语言:javascript代码运行次数:0运行复制@immutable

abstract class Widget extends DiagnosticableTree {

const Widget({ this.key });

final Key key;

@protected

Element createElement();

@override

String toStringShort() {

return key == null ? '$runtimeType' : '$runtimeType-$key';

}

@override

void debugFillProperties(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。

有关Key和Widget复用的细节将会在本书后面高级部分深入讨论,读者现在只需知道,为Widget显式添加key的话可能(但不一定)会使UI在重新构建时变的高效,读者目前可以先忽略此参数。本书后面的示例中,只会在构建列表项UI时会显式指定Key。

另外Widget类本身是一个抽象类,其中最核心的就是定义了createElement()接口,在Flutter开发中,我们一般都不用直接继承Widget类来实现一个新组件,相反,我们通常会通过继承StatelessWidget或StatefulWidget来间接继承Widget类来实现。StatelessWidget和StatefulWidget都是直接继承自Widget类,而这两个类也正是Flutter中非常重要的两个抽象类,它们引入了两种Widget模型,接下来我们将重点介绍一下这两个类。

2.1.2 无状态StatelessWidgetStatelessWidget相对比较简单,它继承自Widget类,重写了createElement() 方法:

代码语言:javascript代码运行次数:0运行复制@override

StatelessElement createElement() => new StatelessElement(this);StatelessElement 间接继承自Element类,与StatelessWidget相对应(作为其配置数据)。

StatelessWidget用于不需要维护状态的场景,它通常在build方法中通过嵌套其它Widget来构建UI

如下下代码所示是无状态 Widget 的简单实现。继承 StatelessWidget,通过 build 方法返回一个布局好的控件。可能现在你还对 Flutter 的内置控件不熟悉,but Don't worry , take it easy ,后面我们就会详细介绍这里你只需要知道,一个无状态的 Widget 就是这么简单。

Widget 和 Widget 之间通过 child: 进行嵌套。其中有的 Widget 只能有一个 child,比如下方的 Container ;有的 Widget 可以多个 child ,也就是children,比如` Column 布局,下方代码便是 Container Widget 嵌套了 Text Widget。

代码语言:javascript代码运行次数:0运行复制import 'package:flutter/material.dart';

class DEMOWidget extends StatelessWidget {

final String text;

//数据可以通过构造方法传递进来

DEMOWidget(this.text);

@override

Widget build(BuildContext context) {

//这里返回你需要的控件

//这里末尾有没有的逗号,对于格式化代码而已是不一样的。

return Container(

//白色背景

color: Colors.white,

//Dart语法中,?? 表示如果text为空,就返回尾号后的内容。

child: Text(text ?? "这就是无状态DMEO"),

);

}

}

build方法有一个context参数,它是BuildContext类的一个实例,表示当前widget在widget树中的上下文,每一个widget都会对应一个context对象(因为每一个widget都是widget树上的一个节点)。实际上,context是当前widget在widget树中位置中执行”相关操作“的一个句柄,比如它提供了从当前widget开始向上遍历widget树以及按照widget类型查找父级widget的方法。

2.1.3 有状态StatefulWidget和StatelessWidget一样,StatefulWidget也是继承自Widget类,并重写了createElement() 方法,不同的是返回的Element 对象并不相同;另外StatefulWidget类中添加了一个新的接口createState()。

StatefulWidget的类定义如下:

代码语言:javascript代码运行次数:0运行复制abstract class StatefulWidget extends Widget {

const StatefulWidget({ Key key }) : super(key: key);

@override

StatefulElement createElement() => new StatefulElement(this);

@protected

State createState();

}•

StatefulElement 间接继承自Element类,与StatefulWidget相对应(作为其配置数据)。StatefulElement 中可能会多次调用createState()来创建状态(State)对象。

createState() 用于创建和Stateful widget相关的状态,它在Stateful widget的生命周期中可能会被多次调用。例如,当一个Stateful widget同时插入到widget树的多个位置时,Flutter framework就会调用该方法为每一个位置生成一个独立的State实例,其实,本质上就是一个StatefulElement对应一个State实例。

如下代码,是有状态的widget的简单实现,你需要创建管理的是主要是 State , 通过 State 的 build 方法去构建控件。在 State 中,你可以动态改变数据,在 setState之后,改变的数据会触发 Widget 重新构建刷新,而下方代码中,是通过延两秒之后,让文本显示为 *"这就变了数值"*。

如下代码还可以看出,State 中主要的声明周期有 :

•initState :初始化,理论上只有初始化一次,第二篇中会说特殊情况下。•didChangeDependencies:在 initState 之后调用,此时可以获取其他 State 。•dispose :销毁,只会调用一次。

看到没,Flutter 其实就是这么简单!你的关注点只要在:创建你的 StatelessWidget 或者 StatefulWidget 而已。你需要的就是在 build 中堆积你的布局,然后把数据添加到 Widget 中,最后通过 setState 改变数据,从而实现画面变化。

代码语言:javascript代码运行次数:0运行复制import 'dart:async';

import 'package:flutter/material.dart';

class DemoStateWidget extends StatefulWidget {

final String text;

////通过构造方法传值

DemoStateWidget(this.text);

///主要是负责创建state

@override

_DemoStateWidgetState createState() => _DemoStateWidgetState(text);

}

class _DemoStateWidgetState extends State {

String text;

_DemoStateWidgetState(this.text);

@override

void initState() {

///初始化,这个函数在生命周期中只调用一次

super.initState();

///定时1秒

new Future.delayed(const Duration(seconds: 1), () {

setState(() {

text = "这就变了数值";

});

});

}

@override

void dispose() {

///销毁

super.dispose();

}

@override

void didChangeDependencies() {

///在initState之后调 Called when a dependency of this [State] object changes.

super.didChangeDependencies();

}

@override

Widget build(BuildContext context) {

return Container(

child: Text(text ?? "这就是有状态DMEO"),

);

}

}

← KM男装加盟加盟费用 KM男装加盟加盟多少钱 游易 幻想三国 →

相关时空节点

软件运行时弹出已停止工作的解决方法

软件运行时弹出已停止工作的解决方法

09-14 💫 279
必藏!几款屏幕亮度调节神器,好用到爆

必藏!几款屏幕亮度调节神器,好用到爆

08-10 💫 819
皇马队史最成功的来自8支世界杯冠军国家的球员

皇马队史最成功的来自8支世界杯冠军国家的球员

07-09 💫 323