From entry to actual combat, Flutter
is divided into 23 series
① (Flutter, Dart environment construction), a total of 3 contents have been updated
② (Dart grammar 1 article) A total of 4 contents have been updated
③ (Dart grammar 2 articles) A total of 2 contents Updated④
(Flutter Case Development Chapter) A total of 4 contents have been
updated⑤(Flutter's StatelessWidget, a total of 3 contents have been
updated⑥(Flutter's Basic Widget Chapter) A total of 2 contents have been
updated⑦(Layout Widget Chapter) A total of 1 contents have been updated Updated
⑧ (Flex, Row, Column, Flexible, Stack) 1 content updated
⑨ (Scrolling Widget) 4 content updated
⑩ (Dart's Future and Network) 3 content
updated⑪ (Douban case-1) A total of 3 contents have been
updated⑫(Douban case-2 articles) A total of 3 contents have been updated
Official Documentation Description
Official Video Tutorial
Flutter's YouTube Video Tutorial - Widgets
⑥Flutter's basic Widget articles
Tips
1. Convert Stateless to Stateful shortcut key
Select the Stateless class and press option + enter
2. Extract a widget to shortcut key
option + enter + w
I modified option + command + 2 here
①, the life cycle of Flutter's StatefulWidgetdidUpdateWidget
1. First find the API search widget of the official documentation and find the State
状态对象具有以下生命周期:
框架通过调用 StatefulWidget.createState创建一个State对象。
新创建的State对象与BuildContext相关联。这种关联是永久的:State对象永远不会改变它的 BuildContext。但是,BuildContext本身可以与它的子树一
起在树周围移动。此时,State对象被视为已安装。
框架调用initState。State的子类应该重写 initState以执行依赖于BuildContext或小部件的一次性初始化,当调用initState方法时,它们分别可用作上下
文和 小部件属性。
框架调用didChangeDependencies。State的子类应该覆盖didChangeDependencies以执行涉及 InheritedWidget的初始化。如果调用了
BuildContext.dependOninheritedWidgetofExactType,如果继承的小部件随后发生变化或小部件在树中移动,则将再次调用didChangeDependencies
方法。
此时,State对象已完全初始化,框架可能会多次调用其build方法来获取此子树的用户界面描述。状态对象可以通过调用它们的setState方法自发地请求
重建它们的子树,这表明它们的某些内部状态已经以可能影响该子树中的用户界面的方式发生了变化。
在此期间,父小部件可能会重建并请求更新树中的此位置以显示具有相同 runtimeType和Widget.key的新小部件。发生这种情况时,框架将更新小部件
属性以引用新小部件,然后 以先前的小部件作为參数调用didUpdateWidget方法。状态 对象应覆盖didUpdatewidget以响应其关联小部件中的更改(例
如,启动隐式动画)。框架总是在调用didUpdateWidget之后调用build,这意味着在didUpdateWidget中对setState的任何调用是多余的。
在开发过程中,如果发生热重载(无论是从命令行flutter工具按启动r,还是从 IDE 启动),都会调用reassemble方法。这提供了重新初始化在
initState方法中准备的任何数据的机会。
如果包含State对象的子树从树中移除(例如,因为父级构建了具有不同runtimeType 或Widget.key的小部件),则框架调用deactivate方法。子类应该
重写此方法以清除此对象与树中其他元素之间的任何链接(例如,如果您为祖先提供了指向后代RenderObject的指针),
此时,框架可能会将此子树重新插入树的另一部分。如果发生这种情况,框架将确保调用build以使State对象有机会适应其在树中的新位置。如果框架
确实重新插入此子树,它将在从树中删除子树的动画帧结束之前执行此操作。因此,State对象可以推迟释放大部分资源,直到框架调用它们的dispose
方法。
如果框架在当前动画帧结束时没有重新插入这个子树,框架将调用dispose,这表明这个State对象将永远不会再次构建。子类应覆盖此方法以释放此对
象保留的任何资源(例如,停止任何活动动画)。
在框架调用dispose后,State对象被认为是未挂载的,mounted属性为 false。此时调用setState是错误的。生命周期的这个阶段是终端:无法重新挂载
已释放的State对象。
didUpdateWidget is required to
重新创建widget对象
be called
②, the basic Widget
1. Ordinary textText
/**
* 1、普通文本 Text
* const Text(
String this.data, {
Key? key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
this.textHeightBehavior,
})
*/
class TextDemoWidget extends StatelessWidget {
const TextDemoWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
"早发白帝城\n朝辞白帝彩云间,千里江陵一日还。\n两岸猿声啼不住,轻舟已过万重山。\n",
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis, // 显示省略号
textScaleFactor: 2.0, // 缩放 比原来的是多少倍
style: TextStyle(
fontSize: 30,
color: Colors.red,
fontWeight: FontWeight.bold
),
);
}
}
1. Rendering
main.dart code
import 'package:flutter/material.dart'; // runApp在这个material库里面
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({
Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home:YHiOSHomePage() ,
);
}
}
class YHiOSHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("基础的widget"),
),
// body: YHiOSHomeContent("你好呀 宇夜iOS"),
body: HYiOSContentState(),
);
}
}
class HYiOSContentState extends StatefulWidget {
const HYiOSContentState({
Key? key}) : super(key: key);
@override
State<HYiOSContentState> createState() => _HYiOSContentStateState();
}
class _HYiOSContentStateState extends State<HYiOSContentState> {
@override
Widget build(BuildContext context) {
return TextDemoWidget();
}
}
/**
* 1、普通文本 Text
* const Text(
String this.data, {
Key? key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
this.textHeightBehavior,
})
*/
class TextDemoWidget extends StatelessWidget {
const TextDemoWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
"早发白帝城\n朝辞白帝彩云间,千里江陵一日还。\n两岸猿声啼不住,轻舟已过万重山。\n",
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis, // 显示省略号
textScaleFactor: 2.0, // 缩放 比原来的是多少倍
style: TextStyle(
fontSize: 30,
color: Colors.red,
fontWeight: FontWeight.bold
),
);
}
}
1.2, rich textText.rich
View the subclass of the class using the shortcut key is option + command + b
1.2.1, the use of Text.rich
// 2.富文本
class TextRichDemoWidget extends StatelessWidget {
const TextRichDemoWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text.rich(
TextSpan(
// text: "hello world",
// style: TextStyle(color: Colors.orange, fontSize: 30),
children: [
TextSpan(text: "hello world", style: TextStyle(color: Colors.orange, fontSize: 30)),
TextSpan(text: "hello world", style: TextStyle(color: Colors.red, fontSize: 30)),
WidgetSpan(child: Icon(Icons.favorite,color: Colors.red)),
TextSpan(text: "hello world", style: TextStyle(color: Colors.green, fontSize: 30))
]
)
);
}
}
1.2, rich text renderings
2. Button
2.1. ButtonRaisedButton
RaisedButton(
child: Text("RaisedButton"),
textColor: Colors.white,
color: Colors.orange,
onPressed: () => print("RaisedButton Click"),
)
2.2. ButtonFlatButton
FlatButton(
onPressed:() => print("FlatButton Click"),
color: Colors.purple,
child:Text("FlatButton"),
),
2.3, buttonOutlineButton
OutlineButton(
child: Text("OutlineButton"),
color: Colors.green,
onPressed:() => print("OutlineButton Click"),
)
2.4, buttonFloatingActionButton
放在App下面的floatingActionButton 类似全局按钮
class YHiOSHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("基础的widget"),
),
// body: YHiOSHomeContent("你好呀 宇夜iOS"),
body: HYiOSContentState(),
floatingActionButton:FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => print("FloatingActionButton Click"),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
2.5. Custom Button图标 文字 背景 圆角
FlatButton(
color: Colors.amberAccent,
// 设置圆角
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)
),
child: Row(
// 内容占多少就显示多少
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.favorite,color: Colors.red),
Text("喜欢宇夜iOS")
],
),
onPressed:() {
},
),
2. The renderings and demo codes of various buttons
class ButtonDemoWidget extends StatelessWidget {
const ButtonDemoWidget({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RaisedButton(
child: Text("RaisedButton"),
textColor: Colors.white,
color: Colors.orange,
onPressed: () => print("RaisedButton Click"),
),
// 2. FlatButton
FlatButton(
onPressed:() => print("FlatButton Click"),
color: Colors.purple,
child:Text("FlatButton"),
),
// 3. OutlineButton
OutlineButton(
child: Text("OutlineButton"),
color: Colors.green,
onPressed:() => print("OutlineButton Click"),
),
// 4.
// FloatingActionButton(
// child: Text("FloatingActionButton"),
// onPressed: () => print("FloatingActionButton Click"),
// )
// 5.自定义Button : 图标-文字-背景-圆角
FlatButton(
color: Colors.amberAccent,
// 设置圆角
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)
),
child: Row(
// 内容占多少就显示多少
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.favorite,color: Colors.red),
Text("喜欢宇夜iOS")
],
),
onPressed:() {
},
),
],
);
}
}
3. Pictures
3.1 Picture Image
Load network picture
// 图片 Image
class ImageDemoWidget extends StatelessWidget {
const ImageDemoWidget({
Key? key,
required this.imageUrl,
}) : super(key: key);
final String imageUrl;
@override
Widget build(BuildContext context) {
return Image(
color:Colors.red,
// 混入模式
colorBlendMode: BlendMode.colorDodge,
image: NetworkImage(imageUrl),
height: 200,
width: 200,
fit:BoxFit.contain, // contain 默认 cover 沾满
// fitWidth 宽度一定 高度自适应 fitHeight : 高度一定 宽度自适应
// alignment: Alignment.bottomCenter,
// Alignment 范围 -1 到 1
alignment: Alignment(-1,0),
// 不断重复
repeat: ImageRepeat.repeatY,
);
}
}
3.1 Picture renderings and description of basic properties
colorBlendMode : Blend in mode
image: Image
color : The color setting color will block the image
width, height : Width and height
fit : Adaptation mode: Default, full, constant width, constant height
repeat : When the image is not full, the image is repeated and superimposed
alignment: Alignment The range is -1 to 1
3.2 Pictures Image
Load local pictures
Notes on loading local images
- Need to create
assets
a folderassets
Create a folder under theimages
folder- save the image
images
in- Open the comment
pubspec.yaml
. The code is as follows assets: - assets/images/ -assets
3.2.1 The first way to load local images
Image(
// 1.在Flutter项目中创建一个文件夹,存储图片
// 2. 在pubspec.yaml进行配置
// 3. 使用图片
image: AssetImage("assets/images/ty.jpeg"),
)
3.2.2 The second way to load local images
Image.asset("assets/images/tk.jpeg");