四、Flutter基础
4.1 flutter入口函数
main(List<String> args) {
runApp(myApp());
}
class myApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(
"标题",
style: TextStyle(
fontSize: 30.0,
color: HexColor("999999"),
),
),
),
body: content(),
),
theme: ThemeData(
primaryColor: Colors.white,
),
);
}
}
class content extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text(
"居中显示",
textDirection: TextDirection.ltr,
style: TextStyle (fontSize: 40.0, color: Colors.red),
),
);
}
}
4.2 Text
child: Text(
"这里是标签内容",
textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis,
maxLines: 1,
textScaleFactor: 1.5,
style: TextStyle(
color: HexColor("333333"),
fontSize: 14.0,
fontWeight: FontWeight.w800, // 加粗
),
),
4.3 Container
child: Container(
width: 200.0,
height: 300.0,
// 布局
alignment: Alignment.topRight,
// 边距
padding: EdgeInsets.all(20),
// padding: EdgeInsets.fromLTRB(16, 16, 10, 8),
margin: EdgeInsets.all(20),
// 位移动 x, y, z
transform: Matrix4.translationValues(10, 20, 30),
// 设置。背景颜色、 边框、圆角
decoration: BoxDecoration(
color: HexColor("ff0000"),
border: Border.all(
color: Colors.blue,
width: 2.0
),
borderRadius: BorderRadius.circular(10.0)
),
)
4.4 Image
-
直接显示的图片
child: Image.network( "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fp1.ssl.qhimg.com%2Fdr%2F...", alignment: Alignment.topLeft, fit: BoxFit.cover, // 全部填充并剪切 ), -
圆形图片
child: ClipOval( child: Image.network( "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fp1.s", fit: BoxFit.cover, ), ), -
切圆角
child: Container( width: 300.0, height: 300.0, decoration: BoxDecoration( color: Colors.yellow, borderRadius: BorderRadius.circular(15), image: DecorationImage( image: NetworkImage( "https://gimg2.baidu.com/image_s", ), fit: BoxFit.cover ), ), ) // 如下这里如果换成本地 image: DecorationImage( image: Image.asset("images/master_head_bgImage"), ), // 换成下面这种方式 image: DecorationImage( // image: Image.asset("images/master_head_bgImage"), image: AssetImage("images/master.png"), fit: BoxFit.cover ), -
头像显示
ListTile( leading: CircleAvatar( // 专门用于处理头像的控件 backgroundImage: NetworkImage(this.listData[1]["imageUrl"]), ), title: Text(this.listData[1]["title"]), subtitle: Text(this.listData[1]["subTitle"], maxLines: 1, overflow: TextOverflow.ellipsis,), ) -
加载本地图片
-
在本地 ios 和 安卓同级别目录下建文件夹 images
-
建立 2.0x 和 3.0x 图片文件夹。 1.0x 的放外面
-
在 pubspec.yaml 中引入图片。
flutter: uses-material-design: true assets: - images/master.png - images/2.0x/master.png - images/3.0x/master.png -
这里也可以直接引入。 而不区分2.x 3.x 那其实就是直接加载图片不区分
assets: - images/
-
4.5 ListView
return ListView(
scrollDirection: Axis.vertical,
children: [
ListTile(title: Text("这是标题"), subtitle: Text("这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容."),),
ListTile(title: Text("这是标题"), subtitle: Text("这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容."),),
ListTile(
title: Text("这是标题"),
subtitle: Text("这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容."),
trailing: Image.network("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.n63.com%2Fphotodir%2Fimg.php%2Fthumbnail%2Fchina%2Fyizhenyu%2Fwww.n63.com_dz_f_e_th_fi_f_s_ll.jpg&refer=http%3A%2F%2Fwww.n63.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1632968753&t=6ffdade4c316ba562cde8445890fc692"),
),
ListTile(
title: Text("这是标题"),
subtitle: Text("这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容, 这是描述内容."),
leading: Image.network("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.n63.com%2Fphotodir%2Fimg.php%2Fthumbnail%2Fchina%2Fyizhenyu%2Fwww.n63.com_dz_f_e_th_fi_f_s_ll.jpg&refer=http%3A%2F%2Fwww.n63.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1632968753&t=6ffdade4c316ba562cde8445890fc692"),
),
],
);
4.6 ListView.builder 动态列表
class Content extends StatelessWidget {
List listData = [
{"title" : "ani", "subTitle" : "你终于还是。。。"},
{"title" : "timi", "subTitle" : "你终于还是。。。"},
{"title" : "kangkang", "subTitle" : "你终于还是。。。"},
];
// 这里是练习一下。初始化数据
Content() {
listData.add({"title" : "这是本类创建的时候初始化的数据", "subTitle" : "你终于还是。。。"});
}
// 封装方法
Widget _getListItem(context, index) {
return ListTile(
title: Text(this.listData[index]["title"]),
subtitle: Text(this.listData[index]["subTitle"] + "$index"),
);
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: this.listData.length,
// itemBuilder: (context, index) {
// return ListTile(
// title: Text(this.listData[index]["title"]),
// subtitle: Text(this.listData[index]["subTitle"] + "$index"),
// );
// },
// 下面的就是帮上面的给封装起来
itemBuilder: this._getListItem
);
}
}
4.7 GridView
return GridView.count(
crossAxisCount: 2,
mainAxisSpacing: 10, // y 轴艰巨
crossAxisSpacing: 10, // x 艰巨
padding: EdgeInsets.all(10),
children: [
Text("----"),
Text("----"),
Text("----"),
Text("----"),
Text("----"),
Text("----"),
Text("----"),
],
);
}
return GridView.builder(
padding: EdgeInsets.all(10),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 15.0,
crossAxisSpacing: 15.0
),
itemCount: this.listData.length,
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.red,
width: 1.5
)
),
child: Column(
children: [
Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(this.listData[index]["title"]),
),
SizedBox(height: 10,),
Text(this.listData[index]["subTitle"], style: TextStyle(fontSize: 20, color: Colors.red),)
],
),
);
}
);
Widget _gridViewItem(context, index) {
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.red,
width: 1.5
)
),
child: Column(
children: [
Container(
height: 100,
width: 100,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(this.listData[index]["title"] + " $index"),
),
SizedBox(height: 10,),
Text(this.listData[index]["subTitle"], style: TextStyle(fontSize: 20, color: Colors.red),)
],
),
);
}
4.8 Icon Row
-
注意 Row 的 children 是需要宽度的不然不显示
Row 需要设置 width
Column 需要设置高度
@override Widget build(BuildContext context) { return Container( width: 414, height: 600, padding: EdgeInsets.all(10), decoration: BoxDecoration( color: HexColor("dbdbdb") ), child: Row( // mainAxisAlignment: MainAxisAlignment.center, //居中显示 // mainAxisAlignment: MainAxisAlignment.spaceBetween, // 左右靠边。中间居中 // mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 等分 mainAxisAlignment: MainAxisAlignment.spaceAround, // 两边边距 = 中间间距 / 2 crossAxisAlignment: CrossAxisAlignment.start, // 副轴对齐方式 children: [ JCIcon(Icons.home, bgColor: Colors.blue), JCIcon(Icons.home, bgColor: Colors.yellow), JCIcon(Icons.home, bgColor: Colors.orange), // JCIcon(Icons.home, bgColor: Colors.blue), // JCIcon(Icons.home, bgColor: Colors.yellow), // JCIcon(Icons.home, bgColor: Colors.orange) ], ), ); } class JCIcon extends StatelessWidget { IconData icon; Color bgColor; JCIcon(this.icon, {this.bgColor = Colors.blue}); @override Widget build(BuildContext context) { return Container( width: 100.0, height: 100.0, color: this.bgColor, child: Icon(this.icon, color: Colors.red, size: 30,), ); } }
4.9 布局 Expanded
child: Row(
children: [
Expanded(
flex: 1,
child: JCIcon(Icons.home, bgColor: Colors.yellow)
),
SizedBox(width: 10,),
Expanded(
flex: 2,
child: JCIcon(Icons.search, bgColor: Colors.blue,)
)
]
)
4.10 布局 Stack Align Positioned
-
Stack Align
child: Stack( // alignment: Alignment.center, // alignment: Alignment(1, 1), children: [ Align(alignment: Alignment.topLeft, child: Container(width: 100, height: 100, color: Colors.red,),), Align(alignment: Alignment.center, child: Container(width: 100, height: 100, color: Colors.blue,),), Align(alignment: Alignment.bottomRight, child: Container(width: 100, height: 100, color: Colors.yellow,),), ], ) -
Stack Positioned
child: Stack( children: [ Positioned(child: Container(width: 100, height: 100, color: Colors.red,), left: 0,), Positioned(child: Container(width: 100, height: 100, color: Colors.blue,), right: 0, top: 0,), Positioned(child: Container(width: 100, height: 100, color: Colors.yellow,), left: 200, top: 200,), ], )
4.11 Card AspectRatio. CircleAvatar
child: ListView(
children: [
Card(
margin: EdgeInsets.all(10),
child: Column(
children: [
AspectRatio( // 处理 宽/长 比例显示的图片
aspectRatio: 20/9.0,
child: Image.network(this.listData[1]["imageUrl"], fit: BoxFit.cover,),
),
ListTile(
leading: CircleAvatar( // 专门用于处理头像的控件
backgroundImage: NetworkImage(this.listData[1]["imageUrl"]),
),
title: Text(this.listData[1]["title"]),
subtitle: Text(this.listData[1]["subTitle"], maxLines: 1, overflow: TextOverflow.ellipsis,),
)
],
),
),
],
)
);
4.12 列表动态加载数据
child: ListView(
children: this.listData.map((item){
return Card(
margin: EdgeInsets.all(10),
child: Column(
children: [
AspectRatio( // 处理 宽/长 比例显示的图片
aspectRatio: 20/9.0,
child: Image.network(item["imageUrl"], fit: BoxFit.cover,),
),
ListTile(
leading: CircleAvatar( // 专门用于处理头像的控件
backgroundImage: NetworkImage(item["imageUrl"]),
),
title: Text(item["title"]),
subtitle: Text(item["subTitle"], maxLines: 1, overflow: TextOverflow.ellipsis,),
)
],
),
);
}).toList(),
)
class _MineState extends State<Mine> {
List listIcon = [Icon(Icons.task), Icon(Icons.settings)];
List listTitle = [ {"title" : "我的任务", "icon" : Icon(Icons.task)}, {"title" : "我的钱包", "icon" : Icon(Icons.money)}, {"title" : "设置中心", "icon" : Icon(Icons.settings)}, ];
@override
Widget build(BuildContext context) {
return Container(
child: ListView(
children: this.listTitle.map((item) {
return Column(
children: [
ListTile(
leading: item["icon"],
title: Text(item["title"]),
trailing: Icon(Icons.keyboard_arrow_right),
horizontalTitleGap: 1,
onTap: () {
if (item["title"] == "设置中心") {
JCRouter.push(context, Setting(titleString: "设置中心",));
}
},
),
Divider(height: 0.5, color: HexColor.lineColor,indent: 16,endIndent: 16,)
],
);
}).toList(),
),
);
}
}
4.13 Wrap
child: Wrap(
spacing: 10,
runSpacing: 0.0001,
children: [
MyButton("这是一个按钮"),
MyButton("个按钮"),
MyButton("这是一个按钮个按钮"),
MyButton("这是一个按钮"),
MyButton("这是一个按钮个按钮"),
MyButton("这是个按钮一个按钮"),
MyButton("这是一个按钮"),
MyButton("这是一个按钮"),
MyButton("这是一个按钮"),
],
)
);
4.14 常用统计
-
children 是数组
- Row Column 适用于横向布局,切子视图不能超过父视图宽度。
- ListView 如果横向布局,或者纵向布局超过需要滑动的都是需要使用 ListView
- GridView 相当于 CollectionView 矩阵式布局
- Wrap 和 Row 差不多,横向布局超出父视图宽度的时候,会自动换行。
- Stack 他是一种绝对定位的方式处理子视图
-
children 是对象的容器
- Expanded 适用于左边固定,右边弹性拉伸的横向布局。
- Card 卡片式列表
- ListTile 最常见的 cell 列表
- AspectRatio 控制长宽比