Flutter
入口方法
入口文件:flutter项目的lib目录里面都有一个main.dart这个文件就是flutter的入口文件
入口方法:
void main() {
runApp(MyApp());
}
//简写如下
void main()=>runApp(MyApp());
//其中main方法是dart的入口方法。runApp方法是flutter的入口方法。MyApp是自定义的一个组件。
Container容器组件
allgnment:topCenter:顶部居中对齐 topleft:顶部左对齐 topRight:顶部右对齐 center: 水平垂直居中对齐 centerLeft:垂直居中水平居左对齐centerRight: 垂直居中水平居右对齐 bottomCenter底部居中对齐bottomLeft:底部居左对齐
bottomRight:底部居右对齐
margin:margin属性是表示Container与外部其他组件的距离
padding:padding就是Container的内边距,指Container边缘与Child之间的距离
transform:让Container容易进行一些旋转之类的transform
height:容器高度
width:容器宽度
child:容器子元素
Container组件是作为Center组件的child使用的,我们用它的decoration属性来修饰它,修饰的值是一个BoxDecoration(color: Colors.red)。
设置一下这个BoxDecoration
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title:const Text("你好Flutter")),
body: const MyApp(),
),
));
}
//代码块 statelessW
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return Center(
child: Container(
alignment: Alignment.bottomCenter, //配置Container容器内元素的方位
width: 100,
height: 100,
//transform: Matrix4.translationValues(10, 0, 0),//位移
transform: Matrix4.rotationZ(0.2),//旋转
decoration: BoxDecoration(
color: Colors.yellow, //背景颜色
border: Border.all( //边框
color:Colors.red,
width:2
),
borderRadius: BorderRadius.circular(10),//配置圆角
boxShadow: const[ //配置阴影效果
BoxShadow(
color: Colors.black,
blurRadius: 10.0
)
],
//LinearGradient 背景线性渐变 RadialGradient径向渐变
gradient: const LinearGradient(
colors: [
Colors.red,Colors.yellow
]
)
),
child:const Text("你好Flutter",style:TextStyle(
color: Colors.white
),),
),
);
}
}
color-填充颜色
border-边界线
borderRadius-边界线弧度,设置圆角
boxShadow-设置阴影
gradient-设置渐变
使用container创建一个按钮 👇
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title:const Text("你好Flutter")),
body: Column(
children: [
MyButton()
],
)
))
);
}
class MyButton extends StatelessWidget {
const MyButton({super.key});
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
width: 200,
height: 40,
//margin: const EdgeInsets.all(10), //四周margin
margin: const EdgeInsets.fromLTRB(0, 20, 0, 0),
padding: const EdgeInsets.all(4), //与里面元素间距
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10)
),
child: const Text("按钮",style: TextStyle(
color: Colors.white,
fontSize:20
)),
);
}
}
class MyButton extends StatelessWidget {
const MyButton({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
width: 200,
height: 40,
margin: const EdgeInsets.fromLTRB(0, 20, 0, 0),
decoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(10)),
child: Text(
"按钮",
style: TextStyle(color: Colors.white, fontSize: 20),
));
}
}
Text组件
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title:const Text("你好Flutter")),
body: const Column(
children: [
MyText()
],
)
))
);
}
class MyText extends StatelessWidget {
const MyText({super.key});
Widget build(BuildContext context) {
return Container(
width: 200,
height: 200,
margin:const EdgeInsets.fromLTRB(0, 40, 0, 0),
decoration: const BoxDecoration(
color:Colors.yellow
),
child: const Text("你好我是Flutter你好我是Flutter你好我是Flutter",
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis, //溢出显示几个点
maxLines: 1, //一行
style: TextStyle(
fontSize: 20, //字体
fontWeight: FontWeight.w900,//加粗
color: Colors.red,
fontStyle: FontStyle.italic, //倾斜
letterSpacing: 2, //字间距
decoration: TextDecoration.underline, //字下划线
decorationColor: Colors.black, //下划线颜色
decorationStyle: TextDecorationStyle.dashed //虚线
),//TextStyle
)//Text
);//Container
}
}
Tex组件的几个的属性
style-设置字体样式
fontSize-字号,就是设置字体大小的
fontWeight-自重,就是设置字体粗细的
fontStyle-样式,有normal和italic,就是直体和斜体的区别
letterSpacing-字符的间距
decoration: TextDecoration.underline-设置下划线
decorationStyle: TextDecorationStyle.dashed-设置下划线为虚线
decorationColor: Colors.blue-设置下划线颜色
textAlign-对齐方式
maxline-最大行数
overflow: TextOverflow.ellipsis - 溢出、显示省略号
图片组件
1.图片组件介绍
通过Image组件来加载并显示图片Image的数据源可以是asset,文件,内存以及网络。
Image.asset,本地图片
Image.network,远程图片
Image组件属性描述
属性名 | 类型 | 说明 |
---|---|---|
image | ImageProvider | Image显示区域的宽度和高度设置 |
width/hei ght | double | Image显示区域的宽度和高度设置 |
fit | Boxfit | 图片填充模式 |
color | Color | 图片颜色 |
colorBlendMode | BlendMode | 在对图片进行手动处理的时候,可能会用到图片混合如改变图片的颜色。此属性可以对颜色进行混合处理。 |
alignment | Alignment | 控制图片的摆放位置 |
repeat | ImageRepeat | 设置图片重复模式 |
centerSlice | Rect | 当图片需要被拉伸时使用 |
matchTextDirection | booI | 该属性与Directionlity配合使用 |
gaplessPlayback | bool | 当ImageProvide发生变化后,重新加载图片的过程中,原图片的展示是否保留 |
BoxFit取值描述
取值 | 描述 |
---|---|
Boxfit.fill | 全图显示,显示可能拉伸,充满 |
Boxfit.contain | 全图显示,显示原比例,不需充满 |
Boxfit. cover | 显示可能拉伸,可能裁剪,充满 |
BoxFit.fitWidth | 显示可能拉伸,可能裁剪,宽度充满 |
BoxFit.fitHeight | 显示可能拉伸,可能裁剪,高度充满 |
Boxfit.none | 原始大小 |
BoxFit.scaleDown | 效果和BoxFit.contain差不多,但是此属性不允许显示超过源图片大小,即可小不可大 |
2.加载远程图片
Image.network(src)
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title:const Text("你好Flutter")),
body: const MyAPP()
) ),
);
}
class MyAPP extends StatelessWidget {
const MyAPP({super.key});
Widget build(BuildContext context) {
return Center(
child: Container(
width: 300,
height: 300,
decoration: const BoxDecoration(
color: Colors.green,
),
child:Image.network("https://www.itying.com/themes/itying/images/ionic4.png",
fit: BoxFit.contain,)
),
);
}
}
3.Container实现圆角图片
//3.Container实现圆角图片
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title:const Text("你好Flutter")),
body: Column(
children:const[
MyApp(),
SizedBox(height:20,),
Circular()
],
)
) ,
));
}
class MyAPP extends StatelessWidget {
const MyAPP({super.key});
Widget build(BuildContext context) {
return Center(
child: Container(
margin:EdgeInsets.fromLTRB(0,40,0,0),
width: 300,
height: 300,
decoration: const BoxDecoration(
color: Colors.green,
),
child:Image.network("https://www.itying.com/themes/itying/images/ionic4.png",
fit: BoxFit.contain,)
),
);
}
}
//实现一个圆形图片
class Circular extends StatelessWidget {
const Circular({super.key});
Widget build(BuildContext context) {
return Container(
width: 300,
height: 300,
decoration: const BoxDecoration(
color: Colors.green,
borderRadius:BorderRadius.circular(75),//圆角
image:DecorationImage(
image:NetworkImage("https://www.itying.com/themes/itying/images/ionic4.png",
fit:BoxFit.cover
)
),
);
}
}
4.CliOval实现圆角图片
5.本地图片
创建Images文件夹,配置文件修改
class LoaclImage extends StatelessWidget {
const LoaclImag({super.key});
Widget build(BuildContext context) {
return Container(
width: 300,
height: 300,
decoration: const BoxDecoration(
color: Colors.green,
),
child:Image.asset("images/a.jpeg",fit:BoxFit.cover),
);
}
}
自定义图标
ICON定义
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.yellow,
),
home: Scaffold(
appBar: AppBar(title: const Text("Flutter ICON")),
body: const MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
Widget build(BuildContext context) {
return const Column(
children: [
SizedBox(height: 20,),
Icon(
Icons.home,
size: 40,
color: Colors.red,),
SizedBox(height: 20,),
Icon(
Icons.settings
),
SizedBox(height: 20,),
Icon(
Icons.search),
SizedBox(height: 20,),
Icon(
Icons.personal_injury_outlined
),
],
);
}
}
!(C:\Users\86180\Pictures\Screenshots\屏幕截图 2023-08-06 184241.png)
页面布局
padding组件:
上下左右都有间距
import 'package:flutter/material.dart';
void main() {
runApp(
const MyApp(),
);
}
//代码块 statelessW
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
body: const HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const IconContainer();
}
}
//自定义IconContainer
class IconContainer extends StatelessWidget {
const IconContainer({super.key});
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
height: 120,
width: 120,
color: Colors.red,
child: const Icon(Icons.home,color:Colors.white,size: 28,),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(
const MyApp(),
);
}
//代码块 statelessW
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
body: const HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return IconContainer(Icons.home,);
}
}
//自定义IconContainer
// ignore: must_be_immutable
class IconContainer extends StatelessWidget {
Color color;
IconData icon;
IconContainer(this.icon,{Key?key,this.color=Colors.red}) : super(key: key);
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
height: 120,
width: 120,
color: color,
child: Icon(icon,color:Colors.white,size: 28,),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Row(
children: [
IconContainer(Icons.home),
IconContainer(Icons.search,color:Colors.yellow ,),
IconContainer(Icons.abc_outlined,color: Colors.orange,),
],
);
}
}
//自定义IconContainer
// ignore: must_be_immutable
class IconContainer extends StatelessWidget {
Color color;
IconData icon;
IconContainer(this.icon, {Key? key, this.color = Colors.red})
: super(key: key);
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
height: 120,
width: 120,
color: color,
child: Icon(
icon,
color: Colors.white,
size: 28,
),
);
}
}
Row组件
import 'package:flutter/material.dart';
void main() {
runApp(
const MyApp(),
);
}
//代码块 statelessW
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
body: const HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: double.infinity,
color: Colors.black12,
child: Row(
//外部没有Container 行是自适应的
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
children: [
IconContainer(Icons.home),
IconContainer(Icons.search),
IconContainer(
Icons.ac_unit_sharp,
color: Colors.orange,
),
],
),
);
}
}
//自定义IconContainer
// ignore: must_be_immutable
class IconContainer extends StatelessWidget {
Color color;
IconData icon;
IconContainer(this.icon, {Key? key, this.color = Colors.red})
: super(key: key);
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
height: 120,
width: 120,
color: color,
child: Icon(
icon,
color: Colors.white,
size: 28,
),
);
}
}
Column组件
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: double.infinity,
color: Colors.black12,
child: Column(//列是自适应的
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,//start在左边,end在右边
children: [
IconContainer(Icons.home),
IconContainer(Icons.search),
IconContainer(
Icons.ac_unit_sharp,
color: Colors.orange,
),
],
),
);
}
}
弹性布局:Flex Expanded
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Flex(
direction: Axis.horizontal, //水平效果,同Row设置效果,vertical:列的效果,同Column
children: [
Expanded(
flex: 1,
child: IconContainer(Icons.home), //加上Expanded组件后,元素设置宽度是没有效果的
),
Expanded(
flex: 2,
child: IconContainer(
Icons.ac_unit_sharp,
color: Colors.orange,
),
),
],
);
}
}
//左边自适应,右边固定宽度
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
flex: 1,
child: IconContainer(Icons.home), //加上Expanded组件后,元素设置宽度是没有效果的
),
IconContainer(
Icons.ac_unit_sharp,
color: Colors.orange,
),
],
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(
const MyApp(),
);
}
//代码块 statelessW
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
body: const HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return ListView(
children: [
Container(
width: double.infinity,
height: 200,
color: Colors.black,
),
Row(
children: [
Expanded(
flex: 2,
child: SizedBox(
height: 180,
child: Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
fit: BoxFit.cover,
)),
),
Expanded(
flex: 1,
child: SizedBox(
height: 180,
child: Column(
children: [
Expanded(
flex: 1,
child: SizedBox(
width: double.infinity,
child: Image.network(
"https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/01/0E/ChMkJ1bKwaOINj39AA0G_ijASO0AALGbQOq5P0ADQcW115.jpg",
fit: BoxFit.cover,
),
)),
Expanded(
flex: 2,
child: SizedBox(
width: double.infinity,
child: Image.network(
"https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/02/06/ChMkJlbKyeCIC-SBABiE33zZm4wAALITwH7uzwAGIT3484.jpg",
fit: BoxFit.cover,
),
))
],
),
)),
],
)
],
);
}
}
stack堆叠
-
class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); Widget build(BuildContext context) { return Stack( //堆叠 children: [ Container( height: 400, width: 300, color: Colors.red, ), Container( height: 200, width: 200, color: Colors.yellow, ), const Text("你好flutter") ], ); } }
Flutter Stack Positioned
Stack组件中结合Positioned组件也可以控制每个子元素的显示位置
属性 | 说明 |
---|---|
top | 子元素距离顶部的距离 |
bottom | 子元素距离底部的距离 |
bottomleft | 子元素距离左侧的距离 |
bottomright | 子元素距离右侧的距离 |
bottomchild | 子组件 |
width | 组件的高度(注意:宽度和高度必须是固定值,没法使用double.infinity) |
height | 子组件的高度 |
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Container(
height: 400,
width: 300,
color: Colors.red,
child: Stack(//注意:相对于外部容器进行定位 如果没有外部容器就相对于整个屏幕进行定位
children: [
Positioned(
left: 10,
bottom: 10,
child: Container(
height: 200,
width: 200,
color: Colors.yellow,
),
),
const Positioned(right: 0, bottom: 190, child: Text("你好flutter"))
],
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//获取设备的宽度和高度
final size = MediaQuery.of(context).size;
return Stack(
children: [
ListView(
padding: const EdgeInsets.only(top: 50),
children: const [
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
ListTile(title: Text("我是一个列表1")),
],
),
Positioned(
left: 0,
top: 0,
width: size.width,//配置子元素的宽度和高度 无法使用double.infinity
height: 44,//配置子元素的宽度和高度
child: Row(
children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.center,
height: 44,
color: Colors.black,
child: const Text(
"二级导航",
style: TextStyle(color: Colors.white),
),
))
],
))
],
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//获取设备的宽度和高度
//final size = MediaQuery.of(context).size;
return const Stack(
children: [
Align(
alignment: Alignment.topLeft,
child: Text("收藏"),
),
Align(
alignment: Alignment.topRight,
child: Text("购买"),
)
],
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//获取设备的宽度和高度
//final size = MediaQuery.of(context).size;
return Container(
width: 300,
height: 300,
color: Colors.red,
child: const Align(
alignment: Alignment(1, 1),
child: Text("你好Flutter"),
),
);
}
}
AspectRatio
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//获取设备的宽度和高度
//final size = MediaQuery.of(context).size;
return AspectRatio(
aspectRatio: 2 / 1,//宽高比
child: Container(
color: Colors.red,
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//获取设备的宽度和高度
//final size = MediaQuery.of(context).size;
return ListView(children: const [
Card(
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10)
// ), //圆角
elevation: 10, //阴影深度
margin: EdgeInsets.all(10),//外边距
child: Column(children: [
ListTile(
title: Text("张三", style: TextStyle(fontSize: 28)),
subtitle: Text("高级软件工程师"),//副标题
),
Divider(), //两个view之间的分割线
ListTile(
title: Text(
"电话:xxxxxxxxxxxx",
),
),
ListTile(
title: Text(
"地址:xxxxxxxxxxxx",
),
)
])),
SizedBox(
height: 20,
),
Card(
elevation: 10,
child: Column(children: [
ListTile(
title: Text("李四", style: TextStyle(fontSize: 28)),
subtitle: Text("flutter高级软件工程师"),
),
Divider(),
ListTile(
title: Text(
"电话:xxxxxxxxxxxx",
),
),
ListTile(
title: Text(
"地址:xxxxxxxxxxxx",
),
)
])),
]);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//获取设备的宽度和高度
//final size = MediaQuery.of(context).size;
return ListView(
children: [
Card(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 20,
margin: const EdgeInsets.all(10),
child: Column(
children: [
AspectRatio(
aspectRatio: 16 / 9,
child: Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
fit: BoxFit.cover,
),
),
const ListTile(
title: Text("xxxxxxxx"),
subtitle: Text("xxxxxxxxx"),
)
],
),
),
Card(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 20,
margin: const EdgeInsets.all(10),
child: Column(
children: [
AspectRatio(
aspectRatio: 16 / 9,
child: Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
fit: BoxFit.cover,
),
),
const ListTile(
title: Text("xxxxxxxx"),
subtitle: Text("xxxxxxxxx"),
)
],
),
)
],
);
}
}
Card(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 20,
margin: const EdgeInsets.all(10),
child: Column(
children: [
AspectRatio(
aspectRatio: 16 / 9,
child: Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
fit: BoxFit.cover,
),
),
ListTile( //设置圆形图片方法一
leading: ClipOval(
child: Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
fit: BoxFit.cover,
height: 40,
width: 40,
),
),
title: const Text("xxxxxxxx"),
subtitle: const Text("xxxxxxxxx"),
// const ListTile( //设置圆形图片方法二
// leading: CircleAvatar(
// backgroundImage: NetworkImage("https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0")),
// title: Text("xxxxxxxx"),
// subtitle: Text("xxxxxxxxx"),
// )
)
],
),
),
按钮
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return ListView(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () {
print("ElevatedButton");
},
child: const Text("普通按钮")),
TextButton(onPressed: () {}, child: const Text("文本按钮")),
const OutlinedButton(onPressed: null, child: Text("边框的按钮")),
IconButton(onPressed: () {}, icon: const Icon(Icons.thumb_up))
],
),
const SizedBox(
height: 20,
),
Row(
//图标按钮
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.send),
label: const Text("发送")),
TextButton.icon(
onPressed: () {},
icon: const Icon(Icons.add),
label: const Text("增加")),
OutlinedButton.icon(
onPressed: () {},
icon: const Icon(Icons.info),
label: const Text("消息")),
],
),
Row(
//设置图标按钮及颜色
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.red), //按钮颜色
foregroundColor:
MaterialStateProperty.all(Colors.black)), //文字图标颜色
onPressed: () {
print("ElevatedButton");
},
child: const Text("普通按钮"))
],
),
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
height: 60,
width: 140,
child: ElevatedButton(onPressed: () {}, child: const Text("大按钮")),
),
SizedBox(
height: 40,
width: 100,
child: ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.search),
label: const Text("搜索")),
)
],
),
const SizedBox(
height: 20,
),
Row(
children: [
Expanded(
flex: 1,
child: Container(
margin: const EdgeInsets.all(20), //设置边距
height: 40,
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.red),
foregroundColor:
MaterialStateProperty.all(Colors.white)),
child: const Text("登录"),
)))
],
)
],
);
}
}
圆角及圆形按钮
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all(//圆角
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12)))),
onPressed: () {},
child: const Text("圆角")),
SizedBox(
height: 80,
width: 80,
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all(//圆形
const CircleBorder(
side: BorderSide(width: 2, color: Colors.yellow), //边框
))),
onPressed: () {},
child: const Text("圆角")),
)
],
),
设置按钮边框
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
style: ButtonStyle(side: MaterialStateProperty.all(//修改边框颜色
const BorderSide(width: 1, color: Colors.red))),
onPressed: () {},
child: const Text("带边框的按钮"))
],
)
Wap按钮组件
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10),
child: Wrap(
alignment: WrapAlignment.center, //居中显示 end居右显示
spacing: 10, //水平间距*
runSpacing: 10, //垂直间距*
//direction: Axis.vertical, //垂直排列
children: [
Button("第1课", onPressed: () {}),
Button("第2课", onPressed: () {}),
Button("第3课", onPressed: () {}),
Button("第4课", onPressed: () {}),
Button("第5课", onPressed: () {}),
Button("第6课", onPressed: () {}),
Button("第7课", onPressed: () {}),
Button("第8课", onPressed: () {}),
Button("第9课", onPressed: () {}),
Button("第10课", onPressed: () {}),
Button("第11课", onPressed: () {}),
Button("第12课", onPressed: () {}),
Button("第13课", onPressed: () {}),
Button("第14课", onPressed: () {}),
Button("第15课", onPressed: () {}),
Button("第16课", onPressed: () {}),
Button("第17课", onPressed: () {}),
Button("第18课", onPressed: () {}),
Button("第19课", onPressed: () {}),
Button("第20课", onPressed: () {}),
],
),
);
}
}
//自定义按钮组件
// ignore: must_be_immutable
class Button extends StatelessWidget {
String text; //按钮的文字
void Function()? onPressed; //方法
Button(this.text, {Key? key, required this.onPressed}) : super(key: key);
Widget build(BuildContext context) {
return ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.white),
foregroundColor: MaterialStateProperty.all(Colors.black45)),
onPressed: onPressed,
child: Text(text),
);
}
}
页面
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(10),
children: [
Row(
children: [
Text(
"热搜",
style: Theme.of(context).textTheme.titleLarge,
)
],
),
const Divider(),
Wrap(
spacing: 10,
runSpacing: 10,
children: [
Button("数学", onPressed: () {}),
Button("语文", onPressed: () {}),
Button("英语", onPressed: () {}),
Button("生物", onPressed: () {}),
Button("化学", onPressed: () {}),
Button("物理", onPressed: () {}),
Button("八年级", onPressed: () {}),
Button("六年级", onPressed: () {}),
Button("二年级", onPressed: () {}),
Button("一年级", onPressed: () {}),
],
),
const Divider(),
const SizedBox(
height: 10,
),
Row(
children: [
Text(
"历史记录",
style: Theme.of(context).textTheme.titleLarge,
)
],
),
const Divider(),
const Column(
children: [
ListTile(
title: Text("物理"),
),
Divider(),
ListTile(
title: Text("英语"),
),
Divider(),
ListTile(
title: Text("测试题"),
),
Divider(),
],
),
const SizedBox(
height: 40,
),
Padding(
padding: const EdgeInsets.all(40),
child: OutlinedButton.icon(
//在ListView中自适应
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all(Colors.black45)),
onPressed: () {},
icon: const Icon(Icons.delete),
label: const Text("清空历史记录"),
),
)
],
);
}
}
//自定义按钮组件
// ignore: must_be_immutable
class Button extends StatelessWidget {
String text; //按钮的文字
void Function()? onPressed; //方法
Button(this.text, {Key? key, required this.onPressed}) : super(key: key);
Widget build(BuildContext context) {
return ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.white),
foregroundColor: MaterialStateProperty.all(Colors.black45)),
onPressed: onPressed,
child: Text(text),
);
}
}
Flutter StatelessWidget,StatefulWidget
在Flutter中自定义组件其实就是一个类,这个类需要继承StatelessWidget/StatefulWidget.
StatelessWidget是无状态组件,状态不可变的widget
StatefulWidget是有状态组件,持有的状态可能在widget生命周期改变。
有状态组件
//有状态组件 如果我们想改变页面中的数据的话这个时候就需要用到StatefulWidget
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _numCount = 0;
Widget build(BuildContext context) {
print(_numCount);
return Scaffold(
appBar: AppBar(
title: const Text("Flutter app"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"$_numCount",
style: Theme.of(context).textTheme.headlineLarge,
),
const SizedBox(
height: 100,
),
ElevatedButton(
onPressed: () {
setState(() {
_numCount++;
});
},
child: const Text("增加"))
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_numCount++;
});
},
child: const Icon(Icons.add),
),
);
}
}
动态列表,计数器
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final List<String> _list = [];
//final只能赋一次值,定义数组可增加数组中数量
//const定义时需确定值
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Flutter App")),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
//改变数据必须加上setStat
setState(() {
_list.add("我是一个新增的列表");
});
},
),
body: ListView(
children: _list.map((v) {
return ListTile(
title: Text(v),
);
}).toList(),
),
);
}
}
导航栏
属性名 | 说明 |
---|---|
items | List底部导航条按钮集合 |
iconSize | icon |
currrentIndex | 默认选中第几个 |
onTab | 选中变化回调函数 |
fixedColor | 选中的颜色 |
type | BottomNavigationBarType.fixed BottomNavigationBarType.shifting |
DrawerHeader(
decoration: BoxDecoration(
//color: Colors.yellow,
image: DecorationImage(
image: NetworkImage(
"https://ts1.cn.mm.bing.net/th/id/R-C.eec02321ea106169d757f427b98b358d?rik=%2bgK43uKTPrZbCw&riu=http%3a%2f%2f00.minipic.eastday.com%2f20170823%2f20170823152907_d41d8cd98f00b204e9800998ecf8427e_4.jpeg&ehk=FsISayQ5Gjp%2boHXA8OW7nhrZdn2JEzUKk3lfW%2br0P70%3d&risl=&pid=ImgRaw&r=0"),
fit: BoxFit.cover)),
child: Column(
children: [
ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
"https://sc.68design.net/photofiles/201503/wvFUgWWHXH.jpg"),
),
title: Text(
"张三",
style: TextStyle(color: Colors.red),
),
),
ListTile(
title: Text("邮箱:xxx@qq.com"),
)
],
)),
Flutter UserAccountsDrawerHeader
属性 | 描述 |
---|---|
decoration | 设置顶部背景颜色 |
accountName | 账户名称 |
accountEmail | 账户邮箱 |
currentAccountPicture | 用户头像 |
otherAccountsPictures | 用来设置当前账户其他账户头像 |
margin |
侧边栏(抽屉菜单)
drawer: Drawer(
child: Column(children: [
Row(children: [
Expanded(
flex: 1,
child: UserAccountsDrawerHeader(
accountName: const Text("姓名"),
accountEmail: const Text("邮箱;@qq.com"),
otherAccountsPictures: [
//其他图片
Image.network(
"https://img.zcool.cn/community/0186025d143ecaa8012051cd9c2eb7.jpg@1280w_1l_2o_100sh.jpg"),
Image.network(
"https://img.zcool.cn/community/0186025d143ecaa8012051cd9c2eb7.jpg@1280w_1l_2o_100sh.jpg")
],
currentAccountPicture: const CircleAvatar(
//头像
backgroundImage: NetworkImage(
"https://sc.68design.net/photofiles/201503/wvFUgWWHXH.jpg"),
),
decoration: const BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://clubimg.club.vmall.com/data/attachment/forum/202006/03/210216pnzsu3qfkaq09pv2.jpg"))),
))
]),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.people),
),
title: Text("个人中心"),
),
const Divider(),
const ListTile(
leading: CircleAvatar(
child: Icon(Icons.settings),
),
title: Text("系统设置"),
),
]),
),
TabBar属性
Stack(children: [
Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0"),
Positioned(
bottom: 20,
left: 20,
child: ClipOval(
child: Image.network(
"https://img95.699pic.com/photo/50086/3791.jpg_wh300.jpg!/fh/300/quality/90",
fit: BoxFit.cover,
height: 60,
width: 60,
),
),
),
Positioned(
top: 10,
right: 10,
child: SizedBox(
height: 30,
width: 30,
child: FloatingActionButton(
backgroundColor: Colors.white12,
child: const Icon(Icons.add),
onPressed: () {},
),
)),
]);
Column(children: [
ListTile(
leading: ClipOval(
child: Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
fit: BoxFit.cover,
height: 40,
width: 40,
),
),
title: const Text("张三", style: TextStyle(fontSize: 28)),
subtitle: const Text("数学老师 七年级"), //副标题
),
const Divider(), //两个view之间的分割线
const ListTile(
title: Text(
"电话:xxxxxxxxxxxx",
),
),
const ListTile(
title: Text(
"授课方式:课堂气氛较为活跃,讲课方式有趣",
),
)
])),
const SizedBox(
height: 20,
),
Column(
children: [
Stack(children: [
Image.network(
"https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0"),
Positioned(
bottom: 20,
left: 20,
child: ClipOval(
child: Image.network(
"https://img95.699pic.com/photo/50086/3791.jpg_wh300.jpg!/fh/300/quality/90",
fit: BoxFit.cover,
height: 60,
width: 60,
),
),
),
Positioned(
top: 10,
right: 10,
child: SizedBox(
height: 30,
width: 30,
child: FloatingActionButton(
backgroundColor: Colors.white12,
child: const Icon(Icons.add),
onPressed: () {},
),
)),
]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(
height: 40,
width: 150,
child: OutlinedButton(
onPressed: () {},
child: const Text("学生"),
),
),
SizedBox(
height: 40,
width: 150,
child: OutlinedButton(
onPressed: () {},
child: const Text("老师"),
),
),
],
),
],
);
import 'package:flutter/material.dart';
import './pages/tabs.dart';
import './pages/search.dart';
import './pages/news.dart';
import './pages/form.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
//home: const Tabs(),
initialRoute: "/",
routes: {
"/": (context) => const Tabs(),
"/news": (context) => const NewsPage(),
"/search": (context) => const SearchPage(),
"/form": (context) => const FormPage(),
},
);
}
}
路由跳转
普通路由跳转及传值
//
import 'package:flutter/material.dart';
import '../search.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
//跳转路由
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
return const SearchPage();
}));
},
child: const Text("基本路由跳转")),
],
));
}
}
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
const SearchPage({super.key});
State<SearchPage> createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("搜索页面"),
),
body: const Center(
child: Text("搜索页面"),
),
);
}
}
PageView组件
import 'dart:math';
import 'package:flutter/material.dart';
void main() {runApp(const MyApp());
}
class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key); build(BuildContext context) {return MaterialApp(title: 'test',home: Scaffold(appBar: AppBar(title: const Text('key demo'),),body: const KeyDemo(),),);}
}
class KeyDemo extends StatefulWidget {const KeyDemo({Key? key}) : super(key: key);<StatefulWidget> createState() => _KeyDemo();
}
class _KeyDemo extends State<KeyDemo> {final List<ColorBlock> _list = [const ColorBlock(text: '1'),const ColorBlock(text: '2'),const ColorBlock(text: '3'),const ColorBlock(text: '4'),const ColorBlock(text: '5'),]; build(BuildContext context) {return Column(children: [..._list,ElevatedButton(onPressed: () {_list.removeAt(0);setState(() {});},child: const Text('删除'),)],);}
}
class ColorBlock extends StatefulWidget {final String text;const ColorBlock({Key? key, required this.text}) : super(key: key);<StatefulWidget> createState() => _ColorBlock();
}
class _ColorBlock extends State<ColorBlock> {final color = Color.fromRGBO(Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1.0); build(BuildContext context) {return Container(width: double.infinity,height: 50,color: color,child: Text(widget.text),);}
}
class GlobalKeyDemo extends StatefulWidget {const GlobalKeyDemo({Key? key}) : super(key: key);<StatefulWidget> createState() => _GlobalKeyDemo();
}
class _GlobalKeyDemo extends State<GlobalKeyDemo> {GlobalKey _globalKey = GlobalKey(); build(BuildContext context) {return Column(children: [ColorBlock(key: _globalKey,),ElevatedButton(onPressed: () {/// 通过GlobalKey可以访问组件ColorBlock的内部(_globalKey.currentState as _ColorBlock).setColor();setState(() {});},child: const Text('更新为红色'),)],);}
}
class ColorBlock extends StatefulWidget {const ColorBlock({Key? key}) : super(key: key);<StatefulWidget> createState() => _ColorBlock();
}
class _ColorBlock extends State<ColorBlock> {Color color = Colors.blue;setColor() {color = Colors.red;} build(BuildContext context) {return Container(width: double.infinity,height: 50,color: color,);}
}
class ValueKey<T> extends LocalKey {
const ValueKey(this.value);
final T value;
bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; return other is ValueKey<T> && other.value == value;
}
}
class ObjectKey extends LocalKey {const ObjectKey(this.value);final Object? value; operator ==(Object other) {if (other.runtimeType != runtimeType)return false;/// identical函数: 检查两个引用是否指向同一对象return other is ObjectKey&& identical(other.value, value);}/// ...
}
class UniqueKey extends LocalKey {UniqueKey(); toString() => '[#${shortHash(this)}]';
}
Flutter动画
AnimatedList实现动画列表
AnimatedList 和 ListView 的功能大体相似,不同的是, AnimatedList 可以在列表中插入或删除节点时执行一个动画,在需要添加或删除列表项的场景中会提高用户体验.
AnimatedList 是一个 StatefulWidget,它对应的 State 类型为 AnimatedListState,添加和删除元素的方法位于 AnimatedListState 中:
void insertItem(int index, { Duration duration = _kDuration });
void removeItem(int index, AnimatedListRemovedItemBuilder builder, { Duration duration = _kDuration }) ;
AnimatedList常见属性:
属性 | 描述 |
---|---|
key | globalKey fifinal globalKey = GlobalKey(); |
initialItemCount | 子元素数量 |
itemBuilder | 方法 ( BuildContext context, int index, Animation animation) {} |
关于GlobalKey: 每个 Widget 都对应一个 Element ,我们可以直接对 Widget 进行操作,但是无法直接操作 Widget 对应的 Element 。而 GlobalKey 就是那把直接访问 Element 的钥匙。通过 GlobalKey可以获取到 Widget 对应的 Element 。
Stack(
children: [
//内置的动画
PositionedTransition(
//Tween 补间,表示一个区间值
rect: RelativeRectTween(
//初始位置
begin: const RelativeRect.fromLTRB(x, y,.,.),
//结束位置
end: const RelativeRect.fromLTRB(endX,endY,.,.),
).animate(
CurvedAnimation(
parent: _controller,
curve: Curves.elasticOut,
),
),
child: null,
),
],
);
//拖动的时候不断更新动画,让他满足自己动画的标准
onPanUpdate: (details) {
setState(() {
x += details.delta.dx;
y += details.delta.dy;
endX = 0; \\或者靠右坐标
endY=y;
});
},
//拖动结束后开始动画
onPanEnd: (details) {
_controller.forward();
},
Curves曲线值
属性 | |
---|---|
linear | 匀速的 |
decelerate | 匀减速 |
ease | 开始加速,后面减速 |
easeIn | 开始慢,后面快 |
easeOut | 开始快,后面慢 |
easeInOut | 开始慢,然后加速,最后再减速 |