微信 绑定网站,wordpress 仪表盘命名,下载页面设计,建网站麻烦吗此篇文章用来记录学习Flutter 和 Dart 相关知识 零.Dart基本数据类型
Dart 是一种静态类型的编程语言#xff0c;它提供了一系列基本数据类型#xff0c;用于存储和操作不同种类的数据。以下是 Dart 中的一些基本数据类型以及它们的详细介绍#xff1a;
1. 整数类型#… 此篇文章用来记录学习Flutter 和 Dart 相关知识 零.Dart基本数据类型
Dart 是一种静态类型的编程语言它提供了一系列基本数据类型用于存储和操作不同种类的数据。以下是 Dart 中的一些基本数据类型以及它们的详细介绍
1. 整数类型Integer:
Dart 提供了两种整数类型int 和 num。 int 表示整数可以存储正数、负数和零。 num 是 int 和 double 的超类型可以用来表示整数和浮点数。
int age 30;
num temperature 98.6;2. 浮点数类型Double:
Dart 中的浮点数类型为 double用于表示带有小数点的数值。
double pi 3.14159;3.字符串类型String:
字符串类型用于表示文本数据。 字符串可以由单引号或双引号包围。
String greeting Hello, Dart!;4.布尔类型Boolean:
布尔类型只有两个值true 和 false用于表示逻辑真值和假值。
bool isDartFun true;5.列表类型List:
列表是有序的数据集合可以包含不同类型的元素。 列表使用方括号 [] 定义并可以通过索引访问元素。
Listint numbers [1, 2, 3, 4, 5];6.映射类型Map:
映射是一组键值对的集合其中每个键都与一个值相关联。 映射使用大括号 {} 定义。
MapString, int grades {Alice: 90, Bob: 85, Carol: 92};7.符号类型Symbol: 符号类型用于表示运行时的标识符或运算符。 符号使用 # 符号前缀定义。
Symbol mySymbol #myIdentifier;8.空类型Null:
Dart 有一个特殊的数据类型 Null表示一个空值或缺失值。 在非空安全null-safe的 Dart 中所有的变量默认都不可以为 null需要使用 ? 明确标记为可为 null。
String? nullableString null; // 可为 null 的字符串9.动态类型Dynamic:
dynamic 是 Dart 中的一个特殊类型可以存储任意类型的数据。 使用 dynamic 声明的变量可以在运行时改变其类型。
dynamic dynamicVariable 42;
dynamicVariable Hello;
这些是 Dart 中的一些基本数据类型。Dart 还支持更多高级数据类型例如函数、类、枚举等以便更灵活地处理各种数据和逻辑。此外Dart 2.12 引入了非空安全null safety功能。 注意 Dart 中没有专门的字节数据类型而是使用 int 来表示字节值因为 Dart 的整数类型 int 可以存储 8 位的无符号整数正好对应一个字节。如果你需要表示多个字节的数据可以使用列表 (List) 或字节数组 (Uint8List通常需要导入 dart:typed_data 库)。
一.Dart 一些语法
const:关键字用于声明一个编译时常量
变量声明
const int x 5;构造函数: 用于声明一个可以在编译时确定值的常量构造函数。
class MyClass {final int value;const MyClass(this.value);
}数组和映射字面量: 可以用 const 声明编译时常量的数组和映射。
const Listint numbers [1, 2, 3];
const MapString, int scores {John: 100, Jane: 90};
继承关系 dart有三种方式分别是extends(继承)with混入 implements实现三种可以混合使用其中withimplements后可以多继承用逗号隔开extends后面只能跟一个优先级顺序为withextendsimplements,当withimplements后跟了多个的时候优先级最右边大于左边依次类推例如extends a with b,c implements d,h优先级为cbahd;
函数可选参数 与java不同dart中不支持重载java支持方法重载dart想要实现java类似的效果可以通过可选参数来实现
selectFunction(张三);
selectFunction(李四,type: 1);
selectFunction(王五,type: 1,money: 83.2);void selectFunction(String name,{int? type,double? money}){print(名字$name--类型$type--金额$money);
}
//注意dart可选参数必须要加来表示该参数默认值为null如果去掉可以手动写个默认值例如
void selectFunction(String name,{int type 0,double? money}){print(名字$name--类型$type--金额$money);
}
//输出结果名字张三--类型null--金额null
//名字李四--类型1--金额null
//名字王五--类型1--金额83.2 二.Flutter 中的一些基础小部件
Center居中对齐小部件
Center小部件用于在可用空间内使其子小部件水平和垂直居中对齐。它接受一个需要居中的子小部件。Center小部件将扩展以填充父小部件的所有可用空间并在该空间内居中其子小部件。
Center(child: Text(Hello, Flutter!,style: TextStyle(fontSize: 24.0),),
)
Text文本小部件
Text小部件用于在屏幕上显示一行文本。可以自定义文本的样式例如字体大小、颜色和对齐方式。通过将字符串传递给Text小部件的data参数可以设置文本的内容。
常用的Text属性
dataString要显示的文本内容。styleTextStyle定义文本的样式如字体、大小、颜色等。textAlignTextAlign指定文本在水平方向上的对齐方式。 –TextAlign.left文本左对齐。 –TextAlign.right文本右对齐。 –TextAlign.center文本居中对齐。 –TextAlign.justify文本两端对齐会调整单词和字之间的间隔。textDirectionTextDirection指定文本的方向如从左到右或从右到左。textScaleFactordouble指定文本的缩放比例。maxLinesint指定允许的最大行数超过将使用…截断。overflowTextOverflow定义文本溢出时的处理方式。softWrapbool指定文本是否自动换行。 body: Center(child: Text(Hello, Flutter!,style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold,color: Colors.blue,),),),Button(按钮)
RaisedButton
RaisedButton 是一个具有凸起效果的按钮通常用于主要操作。
它具有各种自定义属性如 onPressed、child、color、disabledColor、textColor 等以定制外观和行为。
RaisedButton(onPressed: () {// 按钮被点击时执行的操作},child: Text(Submit),
)
FlatButton
FlatButton 是一个扁平化的按钮通常用于次要操作。
它有类似于 RaisedButton 的自定义属性可以根据需求进行定制。
FlatButton(onPressed: () {// 按钮被点击时执行的操作},child: Text(Cancel),
)
OutlineButton
OutlineButton 是一个带有边框的按钮通常用于取消操作或与背景区分。
它也有类似于 RaisedButton 的自定义属性以便自定义外观和行为。
OutlineButton(onPressed: () {// 按钮被点击时执行的操作},child: Text(Clear),
)
FloatingActionButton
FloatingActionButton 是一个圆形的浮动操作按钮常用于应用程序的主要操作。
它也具有各种自定义属性和样式可以根据需求进行调整。
FloatingActionButton(onPressed: () {// 按钮被点击时执行的操作},child: Icon(Icons.add),
)
IconButton
IconButton 是一个只包含图标的按钮通常用于具有图标表示的操作。
它也有各种自定义属性和样式以便自定义外观和行为。
IconButton(onPressed: () {// 按钮被点击时执行的操作},icon: Icon(Icons.favorite),
)
Container容器小部件
Container小部件是一个多用途灵活的小部件可以包含其他小部件。允许自定义属性如宽度、高度、填充、边距、颜色等以控制其子小部件的布局和外观。它还可以对子小部件应用变换、装饰和约束。
Container(width: 200.0,height: 100.0,color: Colors.blue,child: Center(child: Text(Hello, Flutter!,style: TextStyle(fontSize: 24.0, color: Colors.white),),),
)
Row和Column行和列小部件
这些布局小部件用于将其子小部件按水平Row或垂直Column线排列。它们可以包含多个子小部件并根据子小部件的属性和可用空间自动调整大小和位置。可以使用特定参数控制子小部件的对齐方式、间距和调整大小的行为。
Row小部件具有以下一些常用的属性
childrenListWidget需要包含在Row中的子部件列表。mainAxisAlignmentMainAxisAlignment子部件在主轴方向上的对齐方式默认是start。crossAxisAlignmentCrossAxisAlignment子部件在交叉轴方向上的对齐方式默认是start。mainAxisSizeMainAxisSizeRow在主轴方向上的大小约束默认是MainAxisSize.max。textDirectionTextDirection子部件的文本方向默认是TextDirection.ltr。verticalDirectionVerticalDirection子部件在垂直方向上布局的方向默认是VerticalDirection.down。 body: Row(mainAxisAlignment: MainAxisAlignment.center, // 在水平方向上居中对齐crossAxisAlignment: CrossAxisAlignment.start, // 在垂直方向上上对齐mainAxisSize: MainAxisSize.min, // 占用尽可能少的水平空间textDirection: TextDirection.ltr, // 子部件的文本方向从左到右verticalDirection: VerticalDirection.down, // 从上到下布局children: [Text(First Item,style: TextStyle(fontSize: 24),),SizedBox(width: 20), // 在子部件之间增加间距Text(Second Item,style: TextStyle(fontSize: 24),),Container(color: Colors.blue,width: 200,height: 200,child: Text(Third Item,style: TextStyle(fontSize: 24, color: Colors.white),),),],),Column小部件具有以下一些常用的属性
childrenListWidget需要包含在Column中的子部件列表。mainAxisAlignmentMainAxisAlignment子部件在主轴方向上的对齐方式默认是start。crossAxisAlignmentCrossAxisAlignment子部件在交叉轴方向上的对齐方式默认是start。mainAxisSizeMainAxisSizeColumn在主轴方向上的大小约束默认是MainAxisSize.max。verticalDirectionVerticalDirection子部件在垂直方向上布局的方向默认是VerticalDirection.down。
body: Column(mainAxisAlignment: MainAxisAlignment.center, // 在垂直方向上居中对齐crossAxisAlignment: CrossAxisAlignment.start, // 在水平方向上左对齐mainAxisSize: MainAxisSize.min, // 占用尽可能少的垂直空间verticalDirection: VerticalDirection.down, // 从上到下布局children: [Text(First Item,style: TextStyle(fontSize: 24),),SizedBox(height: 20), // 在子部件之间增加间距Text(Second Item,style: TextStyle(fontSize: 24),),Container(color: Colors.blue,width: 200,height: 200,child: Text(Third Item,style: TextStyle(fontSize: 24, color: Colors.white),),),],),Image图像小部件
Image小部件用于在屏幕上显示图像。它支持各种图像来源例如本地资源、网络图像和内存图像。可以自定义其属性如大小、缩放和对齐方式以及处理加载和错误状态。
Image(image: AssetImage(assets/images/flutter_logo.png),width: 100.0,height: 100.0,
)
StatelessWidget和StatefulWidget
StatelessWidget StatelessWidget是一种无状态的小部件意味着它在创建后是不可变的不会随时间改变。它基于构建函数的输入参数一旦构建完成就渲染出静态的用户界面。简单来说StatelessWidget没有内部状态state。
import package:flutter/material.dart;class MyWidget extends StatelessWidget {final String text;MyWidget({required this.text});overrideWidget build(BuildContext context) {return Container(child: Text(text),);}
}
StatefulWidget StatefulWidget是一种有状态的小部件它的内部状态可以随时间变化所以它可以在创建后重新构建。StatefulWidget由两个部分组成一个是State对象用于保存和管理小部件的状态另一个是StatefulWidget类本身用于构建小部件的UI。
import package:flutter/material.dart;class CounterWidget extends StatefulWidget {override_CounterWidgetState createState() _CounterWidgetState();
}class _CounterWidgetState extends StateCounterWidget {int _counter 0;void _incrementCounter() {setState(() {_counter;});}overrideWidget build(BuildContext context) {return Column(children: [Text(Counter: $_counter),ElevatedButton(onPressed: _incrementCounter,child: Text(Increment),),],);}
}
GestureDetector
用于处理用户手势和触摸事件。它可以用于识别和响应各种手势如点击、长按、拖动、缩放和滑动等。GestureDetector 可以包裹任何其他小部件并通过回调函数来响应不同的手势事件。
GestureDetector 的常用属性和介绍
onTap: 当用户轻触手势时触发的回调函数。onDoubleTap: 当用户双击手势时触发的回调函数。onLongPress: 当用户长按手势时触发的回调函数。onLongPressMoveUpdate: 当用户在长按手势的情况下移动时触发的回调函数。onVerticalDragDown: 当用户在垂直方向开始拖动手势时触发的回调函数。onVerticalDragEnd: 当用户在垂直方向结束拖动手势时触发的回调函数。onScaleStart: 当用户开始缩放手势时触发的回调函数。onScaleUpdate: 当用户进行缩放手势时触发的回调函数。behavior: 用于指定如何识别和处理手势事件的 HitTestBehavior。
使用示例
import package:flutter/material.dart;class MyGestureDetector extends StatelessWidget {overrideWidget build(BuildContext context) {return GestureDetector(// 点击事件onTap: () {print(onTap);},// 双击事件onDoubleTap: () {print(onDoubleTap);},// 长按事件onLongPress: () {print(onLongPress);},// 缩放手势onScaleStart: (details) {print(onScaleStart: ${details.focalPoint});},onScaleUpdate: (details) {print(onScaleUpdate: ${details.focalPoint}, ${details.scale});},onScaleEnd: (details) {print(onScaleEnd: ${details.velocity});},// 拖动手势onPanStart: (details) {print(onPanStart: ${details.globalPosition});},onPanUpdate: (details) {print(onPanUpdate: ${details.globalPosition});},onPanEnd: (details) {print(onPanEnd: ${details.velocity});},// 指针击中测试behavior: HitTestBehavior.opaque,// 点击区域的命中测试hitTestBehavior: HitTestBehavior.translucent,// 排除特定手势excludeFromSemantics: true,// 双击事件的时间窗口doubleTapTimeout: Duration(milliseconds: 300),// 长按事件的时间窗口longPressTimeout: Duration(milliseconds: 500),// 长按事件的触发间隔longPressMoveUpdateDelay: Duration(milliseconds: 200),// 其它属性dragStartBehavior: DragStartBehavior.start,child: Container(width: 200,height: 200,color: Colors.blue,),);}
}
Stack
Stack 是一个用于将多个小部件Widgets叠加在一起的布局小部件。Stack 允许您将小部件堆叠在其他小部件之上这样可以创建各种复杂的布局例如叠加式用户界面元素重叠的图像和文本等。
Stack 的主要特点和用法包括 子部件的堆叠Stack 可以包含多个子部件它们会按照添加的顺序堆叠在一起。最后添加的子部件位于最上面。 定位子部件通过 Positioned 小部件您可以精确控制子部件在 Stack 中的位置。通过设置 left、top、right 和 bottom 属性您可以指定子部件的左上角和右下角在 Stack 中的位置。 溢出处理当子部件的大小超出 Stack 的边界时您可以使用 overflow 属性来指定如何处理溢出内容。常见的选项包括 Overflow.clip剪切超出边界的部分和 Overflow.visible允许子部件超出边界。 Alignment您可以使用 alignment 属性来控制 Stack 中所有子部件的对齐方式。这会影响所有子部件的位置除非子部件自身使用 Positioned 进行了具体定位。
示例
Stack(alignment: Alignment.center, // 子部件的默认对齐方式children: Widget[Container(width: 200,height: 200,color: Colors.blue,),Positioned(left: 50,top: 50,child: Container(width: 100,height: 100,color: Colors.red,),),Positioned(right: 50,bottom: 50,child: Container(width: 100,height: 100,color: Colors.green,),),],
)
Align
Align 是一个用于将单个子部件Widget相对于父部件进行对齐的小部件。Align 允许您精确控制子部件在父部件内的位置并指定子部件在水平和垂直方向上的对齐方式。
Align 小部件的主要属性包括 alignmentalignment 属性是 Alignment 类型的用于指定子部件在父部件中的对齐方式。Alignment 使用 Alignment.x 和 Alignment.y 的值来表示水平和垂直方向上的对齐它的取值范围是从 -1.0 到 1.0其中 -1.0 表示左侧或顶部1.0 表示右侧或底部0.0 表示居中。 childchild 属性用于指定要对齐的子部件。这是一个单一的小部件通常是一个容器或其他UI元素。
示例
Align(alignment: Alignment.center, // 将子部件居中对齐child: Container(width: 100,height: 100,color: Colors.blue,child: Text(Centered, style: TextStyle(color: Colors.white)),),
) 三.对齐 widgets
mainAxisAlignment和crossAxisAlignment是用于定位和对齐子部件的属性它们通常用于Flex、Row和Column等布局小部件中。 mainAxisAlignment的值可以是以下之一
MainAxisAlignment.start将子部件沿主轴的起始位置对齐。MainAxisAlignment.end将子部件沿主轴的结束位置对齐。MainAxisAlignment.center将子部件沿主轴的中心位置对齐。MainAxisAlignment.spaceBetween将子部件均匀地分布在主轴上使它们之间的间距相等第一个子部件放置在起始位置最后一个子部件放置在结束位置。MainAxisAlignment.spaceAround将子部件均匀地分布在主轴上使它们之间和两端的间距相等。MainAxisAlignment.spaceEvenly将子部件均匀地分布在主轴上使它们之间的间距和两端的间距相等。
mainAxisAlignment使用示例
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [Container(color: Colors.red, width: 50, height: 50),Container(color: Colors.green, width: 50, height: 50),Container(color: Colors.blue, width: 50, height: 50),],
)
crossAxisAlignment的值可以是以下之一
CrossAxisAlignment.start将子部件沿副轴的起始位置对齐。CrossAxisAlignment.end将子部件沿副轴的结束位置对齐。CrossAxisAlignment.center将子部件沿副轴的中心位置对齐。CrossAxisAlignment.stretch将子部件沿副轴拉伸以填充可用空间。CrossAxisAlignment.baseline将子部件的基线与副轴上的基准线对齐需要在子部件上设置基线对齐方式如TextBaseline。
crossAxisAlignment使用示例
Column(crossAxisAlignment: CrossAxisAlignment.center,children: [Container(color: Colors.red, width: 50, height: 50),Container(color: Colors.green, width: 50, height: 50),Container(color: Colors.blue, width: 50, height: 50),],
) 四.调整widgets大小
Expanded widget 用于在父部件的剩余可用空间中扩展一个子部件。它通常与Flex、Column或Row等灵活的布局小部件一起使用以便在父部件中使用弹性盒子模型进行布局。
当Expanded小部件包装在一个子部件周围时它会将该子部件填充并扩展到可用空间的剩余部分以沿着主轴方向占据所有剩余的空间。这使得子部件能够灵活地从父部件中分配和占据可用空间而不受其自身固定大小的限制。
使用示例
Row(children: [Container(color: Colors.red, width: 50, height: 50),Expanded(child: Container(color: Colors.green),),Container(color: Colors.blue, width: 50, height: 50),],
)
Flex Flex用于创建灵活的布局可以根据可用空间的大小动态调整子部件的大小。可以将 Flex 小部件作为Expanded的子部件并通过指定flex属性来控制子部件在可用空间中的分配比例。 可以简单理解为LinearLayout中的权重
使用示例
Row(children: [Container(color: Colors.red, width: 50, height: 50),Expanded(flex: 2,child: Container(color: Colors.green),),Expanded(flex: 1,child: Container(color: Colors.blue),),],
)
当一个Expanded组件包含在一个垂直方向或水平方向的Flex容器如Column或Row中时该Expanded组件会将其子组件填充到相应方向上的所有可用空间。如果有多个垂直方向的Expanded组件则它们会按照它们的flex属性默认为1来分配可用空间。
换句话说Expanded组件在默认情况下会尽可能地扩展以填充Flex容器中剩余的可用空间但具体的高度取决于Flex容器的大小和其他子组件的约束条件
五.通用布局 widgets
标准 widgets Container向 widget 增加 padding、margins、borders、background color 或者其他的“装饰”。 GridView将 widget 展示为一个可滚动的网格。 ListView将 widget 展示为一个可滚动的列表。 Stack将 widget 覆盖在另一个的上面。
Material widgets Card将相关信息整理到一个有圆角和阴影的盒子中。 ListTile将最多三行的文本、可选的导语以及后面的图标组织在一行中。 六.输入表单
TextField (文本框)
用于接收用户输入文本的小部件它提供了一个可编辑的文本框用户可以在其中输入、编辑和选择文本。
常用的属性及其作用
controller: 一个 TextEditingController 对象用于控制文本输入框的值获取输入的内容或设置初始值。focusNode: 一个 FocusNode 对象用于管理输入框的焦点。decoration: InputDecoration 类型的对象用于定义输入框的外观包括标签文本、提示文本、边框样式等。keyboardType: TextInputType 枚举类型指定键盘的类型以匹配输入的预期内容如文本、数字、URL、电子邮件等。textInputAction: TextInputAction 枚举类型定义了与输入框关联的操作按钮的行为如完成、下一步、搜索等。onChanged: 输入内容变化时的回调函数接受最新的输入值作为参数通常用于实时校验或更新状态。onSubmitted: 用户提交输入后的回调函数接受最终的输入值作为参数。obscureText: bool 值用于指定是否要隐藏输入内容常用于密码输入框。maxLines: int 值用于指定输入框的最大行数。maxLength: int 值用于指定最大输入长度。enabled: bool 值用于指定输入框是否可编辑。autofocus: bool 值用于指定是否自动获取焦点。textAlign: TextAlign 枚举类型指定文本内容的对齐方式如左对齐、右对齐、居中等。cursorColor: Color 对象指定光标的颜色。cursorWidth: double 值用于指定光标的宽度。
使用示例
import package:flutter/material.dart;class MyTextField extends StatefulWidget {override_MyTextFieldState createState() _MyTextFieldState();
}class _MyTextFieldState extends StateMyTextField {TextEditingController _controller TextEditingController();FocusNode _focusNode FocusNode();overridevoid dispose() {_controller.dispose();_focusNode.dispose();super.dispose();}overrideWidget build(BuildContext context) {return TextField(controller: _controller,focusNode: _focusNode,decoration: InputDecoration(labelText: Enter your name,hintText: John Doe,prefixIcon: Icon(Icons.person),suffixIcon: IconButton(icon: Icon(Icons.clear),onPressed: () {_controller.clear();},),border: OutlineInputBorder(),),keyboardType: TextInputType.text,textInputAction: TextInputAction.done,onChanged: (value) {print(Input: $value);},onSubmitted: (value) {print(Submitted: $value);_focusNode.unfocus();},);}
}
关于TextEditingController和FocusNode的介绍
TextEditingController TextEditingController是一个控制文本输入的类它提供了一些方法和属性来获取和修改TextField中输入的文本。主要作用包括
可以获取TextField中的文本内容使用text属性可以获取TextField中当前的文本内容。可以设置TextField的初始值或修改文本内容使用text属性可以设置TextField的初始值也可以通过textEditingController.text newText来修改文本内容。可以监听文本变化可以通过注册addListener()方法来监听TextField中的文本变化以便执行特定的操作。
FocusNode FocusNode是用于处理TextField焦点的类它允许管理应用程序中的焦点并监听焦点变化事件。主要作用包括
管理TextField的焦点通过将TextField的focusNode属性设置为FocusNode对象可以管理TextField的焦点。例如可以使用focusNode.requestFocus()请求焦点并使用focusNode.unfocus()取消焦点。监听焦点变化可以通过注册addListener()方法来监听焦点的变化以便在焦点状态发生变化时执行特定的操作比如显示或隐藏键盘。控制键盘行为通过设置keyboardType和textInputAction属性可以控制键盘的类型例如纯文本、数字等和键盘完成按钮的样式例如完成、下一个等。
TextFormField (表单文本框)
TextFormField 是一个带有表单功能的文本输入字段小部件。它是基于 TextField 的封装并提供了一些额外的功能如表单验证和错误处理。
常用属性及其作用 controller: 一个 TextEditingController 对象用于控制文本输入框的值获取输入的内容或设置初始值。 focusNode: 一个 FocusNode 对象用于管理输入框的焦点。 decoration: InputDecoration 类型的对象用于定义输入框的外观包括标签文本、提示文本、边框样式等。 keyboardType: TextInputType 枚举类型指定键盘的类型以匹配输入的预期内容如文本、数字、URL、电子邮件等。 textInputAction: TextInputAction 枚举类型定义了与输入框关联的操作按钮的行为如完成、下一步、搜索等。 validator: 一个函数接受输入的字符串根据需求返回一个错误提示字符串用于对输入内容进行验证。 onChanged: 输入内容变化时的回调函数接受最新的输入值作为参数通常用于实时校验或更新状态。 onFieldSubmitted: 用户提交输入后的回调函数接受最终的输入值作为参数。
使用示例
import package:flutter/material.dart;class MyForm extends StatefulWidget {override_MyFormState createState() _MyFormState();
}class _MyFormState extends StateMyForm {final _formKey GlobalKeyFormState();TextEditingController _nameController TextEditingController();overrideWidget build(BuildContext context) {return Form(key: _formKey,child: TextFormField(controller: _nameController,decoration: InputDecoration(labelText: Name,hintText: Enter your name,),validator: (value) {if (value.isEmpty) {return Please enter your name;}return null;},onFieldSubmitted: (value) {if (_formKey.currentState.validate()) {// 执行提交操作}},),);}
} 七.关键词
part
用于将多个Dart文件组织在一起以便更好地管理和维护代码。
part 指令是Dart语言的一部分它允许你将一个Dart文件分成多个部分并将它们组合在一起以形成一个完整的库。这对于将大型代码库分解为更小的可管理部分非常有用。
part ‘WeiBoCommentList.g.dart’; 表示当前的Dart文件是一个库的一部分并且需要引入另一个名为 WeiBoCommentList.g.dart 的Dart文件以共享一些代码或声明。
通常part 指令在使用代码生成工具时非常有用例如json_serializable或moor_generator。这些工具可以根据模型类自动生成代码而将生成的代码放在单独的文件中然后使用 part 指令将其引入到主要的模型文件中。
例如假设 WeiBoCommentList.g.dart 包含自动生成的序列化或数据库访问代码而 WeiBoCommentList.dart 包含模型类的定义。通过使用 part 指令你可以将自动生成的代码与手动编写的代码分离开来以便更轻松地维护和管理项目。
Completer
Completer 是一个用于处理异步操作的类它允许你手动控制异步操作的完成和结果返回。Completer 的主要作用是创建一个 Future 对象并允许你在某个后续时刻手动完成这个 Future从而传递一个值或错误。
以下是 Completer 的主要作用 手动完成 Future使用 Completer你可以创建一个未来的实例并在需要的时候手动完成它。这对于异步操作如网络请求、文件读写等非常有用因为你可以在操作完成后通过 Completer 将结果传递给等待的代码。 处理异步操作的结果当你使用异步操作时通常需要等待操作完成并获取结果。通过 Completer 创建的 Future你可以使用 await 关键字或 .then() 方法等方式来等待操作完成并获取其结果。
示例
import dart:async;Futurevoid fetchData() async {Completervoid completer Completervoid();// 模拟一个异步操作等待2秒钟后完成Future.delayed(Duration(seconds: 2), () {completer.complete(); // 手动完成Future});await completer.future; // 等待Future完成print(Data fetched successfully);
}void main() {fetchData();print(Fetching data...); // 这一行会在异步操作完成前执行
}
StreamSubscription
StreamSubscription 是使用 Dart 中的流Stream的一种方式。流是一系列异步事件的序列可以用于接收和处理来自异步操作如网络请求、数据库查询等的事件。
StreamSubscription 用于订阅流并可以跟踪和取消订阅。当你订阅一个流时你可以指定一个回调函数来处理流中发出的事件。回调函数会在每个事件到达时被调用而不是等待整个流完成。
订阅流
要订阅流首先需要获取一个流对象。在Flutter中很多类如StreamController、StreamTransformer等都提供了流的实例化和管理。一旦获取到流对象你可以使用stream.listen()方法订阅流并提供一个回调函数来处理流中的事件。
Streamint countStream() async* {for (int i 1; i 5; i) {await Future.delayed(Duration(seconds: 1));yield i;}
}void main() {final stream countStream();final subscription stream.listen((data) {print(Received: $data);});// 取消订阅subscription.cancel();
}
上面的示例中创建了一个简单的计数流countStream()它每隔一秒产生一个整数。我们通过stream.listen()方法订阅了这个流并提供了一个回调函数来处理每个事件。
取消订阅
当不再需要订阅流时应该显式地取消订阅以释放资源和停止事件的处理。可以调用StreamSubscription对象的cancel()方法来取消订阅。
final subscription stream.listen((data) {print(Received: $data);
});// 取消订阅
subscription.cancel();
在上面的示例中保存了StreamSubscription对象到subscription变量中并在不再需要时调用了cancel()方法来取消订阅。
使用StreamSubscription的其他方法和属性
StreamSubscription提供了一些其他有用的方法和属性用于管理订阅和检查流的状态例如
pause()和resume()暂停和恢复订阅以便控制事件的处理。onData()设置一个新的事件回调函数替换原来的回调函数。onError()设置一个错误回调函数用于处理流中的错误事件。onDone()设置一个完成回调函数用于处理流结束时的事件。isPaused一个布尔值表示当前订阅是否已暂停。
mixin
Mixin是一种强大的代码重用机制它允许你将一个类的成员添加到另一个类中而无需继承该类。Mixin提供了一种方式来在类之间共享代码同时保持类之间的分离性。
1. 基本语法
class MyClass with MyMixin {// 类的成员和方法
}mixin MyMixin {// Mixin中的成员和方法
}在上面的代码中MyClass类通过with MyMixin语法引入了MyMixin的功能。
2. Mixin的特点
Mixin类本身不能被实例化它们只能被用作其他类的组成部分。类可以使用多个Mixin通过逗号分隔这允许多个类的功能被组合到一个类中。Mixin可以有自己的属性和方法这些属性和方法可以被包含Mixin的类访问和使用。如果多个Mixin中有同名的方法或属性那么包含Mixin的类必须通过显式指定使用哪个Mixin的方式来解决冲突。Mixin的顺序很重要因为方法冲突时会按照Mixin的顺序来解析。
3. Mixin的应用场景
3.1. 接口实现
Mixin可以用于实现接口允许一个类同时具有多个接口的功能。
class MyWidget with WidgetMixin, ClickableMixin {// ...
}3.2. 功能复用
Mixin可以用于将通用功能添加到多个类中避免重复编写相似的代码。
mixin LoggerMixin {void log(String message) {print(message);}
}class MyClass with LoggerMixin {// ...
}3.3. 数据序列化与反序列化
Mixin可以用于为多个数据模型类添加数据序列化和反序列化的功能。
mixin JsonSerializable {MapString, dynamic toJson();void fromJson(MapString, dynamic json);
}class Person with JsonSerializable {// ...
}3.4. 路由导航
在Flutter中Mixin经常用于处理路由导航以减少页面之间的代码冗余。
3.5. 状态管理
在Flutter中StatefulWidget常常使用Mixin来添加状态管理的功能。
with
with关键字用于在类定义中混入mixin一个或多个 mixin 类。Mixin 是一种在 Dart 中实现代码重用的机制它允许你将一个或多个 mixin 类的特性添加到一个类中而无需继承这些 mixin 类。
使用方式
class MyClass with Mixin1, Mixin2, ... {// 类的成员和方法
}关于 with 关键字的详细介绍 混入Mixin的类with 后面可以跟一个或多个 mixin 类用逗号分隔。这意味着你可以从多个 mixin 类中继承特性将它们组合到一个类中从而实现多重继承的效果。 Mixin的顺序Mixin 的顺序很重要因为如果多个 mixin 类中具有相同名称的属性或方法类中将使用最后一个 mixin 中定义的属性或方法。这个规则确保了 mixin 类的顺序对类的行为产生影响。 Mixin的特性通过使用 with 关键字类将继承 mixin 类的属性、方法和功能这些特性会被添加到类中。这允许你在不继承 mixin 类的情况下使用 mixin 类的功能。 Mixin的用途with 关键字通常用于以下情况
实现接口通过混入一个 mixin 类类可以实现多个接口的功能。代码复用可以将通用功能添加到多个类中以减少代码重复性。实现混合功能在不使用多重继承的情况下将多个 mixin 类的功能组合在一个类中。
dynamic和Object
1、Object 是dart所有对象的根基类也就是说所有类型都是Object的子类所以任何类型的数据都可以赋值给Object声明的对象. 2、dynamic与var一样都是关键词,声明的变量可以赋值任意对象. 而dynamic与Object相同之处在于,他们声明的变量可以在后期改变赋值类型.
typedef
用于创建自定义类型别名type alias。类型别名允许你为现有的数据类型或函数签名定义一个新的名称以便在代码中更清晰地表达类型或函数签名的含义
以下是关于typedef关键字的详细介绍
为数据类型创建类型别名
typedef IntList Listint;
typedef StringMap MapString, String;
为函数签名创建类型别名 对于回调函数或函数参数特别有用
typedef VoidCallback void Function();
typedef BinaryOperation int Function(int, int);
与高阶函数一起使用
typedef FilterFunctionT bool Function(T);ListT filterListT(ListT list, FilterFunctionT filter) {return list.where(filter).toList();
}
get
get关键字用于创建一个Getter方法它允许你访问对象的属性或计算属性的值就像访问类的实例变量一样。Getter方法通常用于获取对象的某个属性值而不是直接访问实例变量以提供更多的封装和控制。
1.创建Getter方法通过在类中定义一个以get关键字开头的方法你可以创建一个Getter方法该方法用于获取某个属性的值。Getter方法的语法如下
Type get propertyName {// 在这里计算和返回属性的值
}其中Type是属性的数据类型propertyName是你希望暴露的属性名称。
2.延迟加载属性Getter方法可以用于延迟加载属性的值。这意味着属性的值只有在首次访问Getter方法时才会计算而不是在对象创建时。这对于节省资源和提高性能很有用。
class LazyLoader {Listint _data [1, 2, 3, 4];int get sum {// 计算并返回列表元素的总和return _data.reduce((a, b) a b);}
}
3.属性访问控制使用Getter方法可以对属性的访问进行控制例如你可以在Getter方法中添加条件来检查属性的有效性然后返回相应的值。
class Temperature {double _celsius;Temperature(this._celsius);double get celsius {if (_celsius -273.15) {throw ArgumentError(Temperature cannot be below absolute zero.);}return _celsius;}
}4.在子类中覆盖Getter方法可以在子类中被覆盖允许你根据需要自定义子类的属性访问行为。
class Parent {int get value 42;
}class Child extends Parent {overrideint get value super.value * 2; // 在子类中覆盖Getter方法
} 未完待续…