一. Widget
1.1. 万物皆是Widget
- Flutter整个应用程序中所看到的内容几乎都是Widget,甚至内边距的设置也是Widget;
- Flutter中的Widget(小部件或者组件),相当于iOS、Android中的控件,相当于Vue、React中的组件;但Fullter中Widget更彻底。
1.2. Material设计风格
- material是Google公司推行的一套设计风格,或者叫设计语言、设计规范等;
- 里面有非常多的设计规范,比如颜色、文字的排版、响应动画与过度、填充等等;
- 在Flutter中高度集成了Material风格的Widget;
二. 实例一 hello flutter
2.1. text
import 'package:flutter/material.dart';
void main() {
runApp(Text('hello flutter', textDirection: TextDirection.ltr));
}
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/fed2efe8ca0323ebaef3d9e06d0ed100.png)
2.2. 居中
void main() {
runApp(
Center(
child: Text(
'hello flutter',
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 30),
)
)
);
}
2.3. 添加导航栏
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("第一个应用程序"),
),
body: Center(
child: Text(
'hello flutter',
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 30),
)
),
)
)
);
}
2.4. 改进
- widget:
- 无状态的Widget: StatelessWidget
- 有状态的Widget: StatefulWidget
- StatefulWidget就是有状态的Widget。它在程序运行时,状态被允许发生改变,要想编写出能够被用户操作的App,就必须要使用StatefulWidget。
void main() {
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage()
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("第一个应用程序!"),
),
body: HHContentBody(),
);
}
}
class HHContentBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'hello flutter',
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 30),
)
);
}
}
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/33d5e09334d476885d64fdc14cf5ff25.png)
三. 案例二 同意协议
- 所有的Widget被注解@immutable修饰,所有成员变量不可变
3.1. 错误代码
class HHContentBody extends StatelessWidget {
var flag = true;
@override
Widget build(BuildContext context) {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Checkbox(value: flag, onChanged: (flag){
ValueKey(flag);
}),
Text('同意协议'),
],
)
);
}
}
3.2. 正确代码
void main() {
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage()
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("第一个应用程序!"),
),
body: HHContentBody(),
);
}
}
class HHContentBody extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return HHContentBodyState();
}
}
class HHContentBodyState extends State<HHContentBody> {
var flag = true;
@override
Widget build(BuildContext context) {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Checkbox(value: flag, onChanged: (value){
print(flag);
setState(() {
flag = value!;
});
}),
Text('同意协议')
],
),
);
}
}
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/962218706bce2ff56b98d4dc2d4ab685.png)
四. 案例三 list列表
- ListView 滚动视图
- Column 垂直视图
- decoration 装饰
- padding 边距
- crossAxisAlignment 交叉轴
- SizedBox 中间件间隔
import 'package:flutter/material.dart';
void main() {
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage()
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('title'),),
body: HomeBody(),
);
}
}
class HomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: [
HomeProductItem('title', 'desc', 'https:
SizedBox(height: 8),
HomeProductItem('title', 'desc', 'https:
SizedBox(height: 8),
HomeProductItem('title', 'desc', 'https:
],
);
}
}
class HomeProductItem extends StatelessWidget {
final String title;
final String desc;
final String imgUrl;
HomeProductItem(this.title, this.desc, this.imgUrl);
@override
Widget build(BuildContext context) {
final style1 = TextStyle(fontSize: 30, color: Colors.blue);
final style2 = TextStyle(fontSize: 20, color: Colors.orange);
return Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
width: 5,
color: Colors.purple
)
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: style1,),
SizedBox(height: 8),
Text(desc, style: style2,),
SizedBox(height: 8),
Image.network(imgUrl)
],
),
);
}
}
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/8f557fc9f6f46ec3fab48d7a3da72746.png)
五. 案例四 加减
- mainAxisAlignment 主轴
- state.widget.params state获取widget的属性
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage()
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('title'),),
body: HomeBody(),
);
}
}
class HomeBody extends StatefulWidget {
final params = 'params';
@override
State<StatefulWidget> createState() {
return _HomeBodyState();
}
}
class _HomeBodyState extends State<HomeBody> {
var num = 0;
final style1 = TextStyle(fontSize: 20, color: Colors.red);
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(onPressed: (){
setState(() {
num--;
});
},
child: Text('-', style: style1)),
ElevatedButton(onPressed: (){
setState(() {
num++;
});
},
child: Icon(Icons.add)),
],
),
Text('当前计数:$num', style: style1),
Text(this.widget.params)
],
),
);
}
}
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/96a96f9bcab85b735cf78943fa2c7061.png)
六. StatefulWidget生命周期
- StatefulWidget本身由两个类组成的:StatefulWidget和State
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/a581aa87defbe86c1ee80f20e392b189.jpeg)