Flutter学习笔记
无状态组件:创建新的类,继承 StatelessWidget 并实现build方法,build返回Widget纯展示型组件,没有用户交互操作@overridetitle: "materialAPP 体验",//设置中部与底部主题),appBar: AppBar(title: Text("头部区域"), centerTitle: true),body: Container(child: Center
1. 创建项目
flutter create --platforms web flutter_demo
注意如果执行命令后什么都不显示,可能是权限不足,使用管理员身份运行PowerShell
看到All done!即可创建成功

2. 运行项目
cd flutter_demo
flutter run -d chrome
进入项目根目录,运行 Web 项目(指定 Chrome 浏览器)


如果遇到该情况(启动失败,打开浏览器,但浏览器显示不出结果),可能是Flutter 启动 Chrome 时的参数组合和浏览器权限冲突。
解决:
用「web-server」模式绕开浏览器启动(最快速验证)
先不通过 Flutter 直接启动浏览器,改用「web 服务器」模式,手动在 Chrome 中打开页面:
# 启动 web 服务器(不自动打开浏览器)
flutter run -d web-server
注意如果执行命令后什么都不显示,可能是权限不足,使用管理员身份运行PowerShell

启动成功后,会输出类似http://localhost:62825 的地址,手动复制这个地址到 Chrome 中打开即可访问项目。

3. 组件学习
3.1基础组件
3.1.1 MaterialAPP
整个应用被MaterialApp包裹,方便对整个应用的属性进行整体设计
void main(List<String> args) {
runApp(
MaterialApp(
title: "materialAPP 体验",//展示标题
theme: ThemeData(scaffoldBackgroundColor: Colors.blueAccent),//设置主题
home: Scaffold(),//展示主体内容, Scaffold()骨架组件
),
);
}

注意如果修改代码后浏览器页面还没有变化,终端输入r实现热重载,再刷新浏览器即可得到修改后的页面展示。

3.1.2 Scaffold

代码展示:
runApp(
MaterialApp(
title: "materialAPP 体验",
theme: ThemeData(
//设置中部与底部主题
scaffoldBackgroundColor: const Color.fromARGB(255, 127, 147, 183),
),
home: Scaffold(
appBar: AppBar(title: Text("头部区域"), centerTitle: true),
body: Container(child: Center(child: Text("中部区域"))),
bottomNavigationBar: Container(
height: 80, //设置底部大小,不然中部与底部无法分开,看不到底部效果
child: Center(child: Text("底部区域")),
),
),
),
);
效果展示:
3.2 自定义组件
3.2.1无状态组件
无状态组件:创建新的类,继承 StatelessWidget 并实现build方法,build返回Widget
纯展示型组件,没有用户交互操作
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "materialAPP 体验",
theme: ThemeData(
//设置中部与底部主题
scaffoldBackgroundColor: const Color.fromARGB(255, 127, 147, 183),
),
home: Scaffold(
appBar: AppBar(title: Text("头部区域"), centerTitle: true),
body: Container(child: Center(child: Text("中部区域"))),
bottomNavigationBar: Container(
height: 80, //设置底部大小,不然中部与底部无法分开,看不到底部效果
child: Center(child: Text("底部区域")),
),
),
);
}
}
3.2.2有状态组件
有状态组件管理变化的内部状态,当状态改变时,组件回更新显示内容

第一个类负责向外接收参数,第二个类向内管理状态
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
//第一个类,创建State对象(接收外部参数)
class MainPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
//返回第二个类的对象
return _MainPageState();
}
}
//第二个类 内部类(私有)继承State<第一个类名>,负责管理数据 处理业务逻辑 渲染视图
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "materialAPP 体验",
theme: ThemeData(
//设置中部与底部主题
scaffoldBackgroundColor: const Color.fromARGB(255, 4, 85, 238),
),
home: Scaffold(
appBar: AppBar(title: Text("头部区域"), centerTitle: true),
body: Container(child: Center(child: Text("中部区域"))),
bottomNavigationBar: Container(
height: 80, //设置底部大小,不然中部与底部无法分开,看不到底部效果
child: Center(child: Text("底部区域")),
),
),
);
}
}
3.3 组件生命周期
3.3.1 无状态组件
唯一阶段:build()方法
当组件被创建或父组件状态变化导致其需要重新构建时,build方法会被调用
3.3.2 有状态组件


InheritedWidget:全局状态(如路由),专门用于Widget树中自顶向下高效地共享数据,顶层组件提供数据,子孙节点直接获取
所有方法均在第二个类中实现(如AState)
3.4 点击事件
3.4.1 GestureDelector
GestureDelector是Flutter中最常用、功能最丰富的手势检测组件
onTap:点击 onDoubleTap:双击 等以on开头的方法
用法:GestureDelector包裹被点击的元素,传入方法(以on开头)
body: Container(
child: Center(
child: GestureDetector(//包裹
// onTap: () { //点击事件
// print("点击了该区域");
// },
onDoubleTap: () {
print("双击该区域");
},
child: Text("中部区域"),//被点击的元素
),
),
),
3.4.2 组件点击事件

body: Container(
child: Center(
child: TextButton(
onPressed: () {
//处理点击逻辑
print("组件点击");
},
child: Text("文本按钮"),
),
),
),
3.5 状态更新
数据的变化要更新UI视图,需要执行setState方法,setState方法会造成build的重新执行
body: Center(
child: Row(
children: [
TextButton(
onPressed: () {
setState(() {
//如不加setState,则页面上count的值永远为1(UI不更新)
count--;
});
},
child: Text("-"),
),
Text(count.toString()),
TextButton(
onPressed: () {
count++;
setState(() {}); //也可以这样写,setState是异步操作,最后执行
},
child: Text("+"),
),
],
),
),
3.6 组件
布局组件

3.6.1 Container组件
相当于HTML的div

常见属性

return MaterialApp(
home: Scaffold(
body: Container(
transform: Matrix4.rotationZ(0.05),//变换角度0.05是弧度而非角度,
margin: EdgeInsets.all(20),//外边距
alignment: Alignment.center,//子组件居中
width: 200,//宽 width:double.infinity正无穷大,填满整个空间宽
height: 200,//高
decoration: BoxDecoration(
color: Colors.blue,//背景颜色
borderRadius: BorderRadius.circular(15),//圆角
border: Border.all(width: 3,color: Colors.yellow)//边框
),
child: Text(//Text内置样式
"hello world ",
style: TextStyle(color: Colors.white, fontSize: 20),
),
//color:Colors.blue 简单的背景与颜色
),
),
);
width:double.infinity正无穷大,填满整个空间宽
3.6.2 Center组件
将子组件在父容器的空间内进行水平和垂直方向上的居中排列
必须有child,默认全部占用父容器空间,若子组件只占用部分父组件,则可以在child中嵌套Container


3.6.3 Align组件


3.6.4 Padding组件
属性:padding,必须有,定义内边距的大小和方向,通常使用EdgeInsets类来设置
所有方向用EdgeInsets.all(),
任意方向用EdgeInsets.only(top: ,bottom: ,left: ,right: ),
对称方向用EdgeInsets.symmetric(horizontal: ,vertical: )
child:需要被添加内边距的子组件
3.6.5 Column组件


3.6.6 Row组件


3.6.7 Flex和Expanded

Flex是Column和Row的结合体

3.6.8 Wrap换行组件


3.6.9 Stack/Position

Stack类似相对定位,后者叠在前者上(children中排列顺序)



3.6.10 Text组件



3.6.11 Image组件



3.6.12 TextField文本输入组件
onSubmitted :电脑端Enter键

注意:

写来试试
3.6.13 SingleChildScrollView组件

3.6.14 ListView组件


3.6.15 GridView组件
3.6.16 CustomScrollView组件
3.6.17 PageView组件
3.7 组件通信

3.7.1 父传子

无状态组件:Child类中定义构造函数(需要的参数),使用传入参数值,父组件的类(或对内类)调用构造函数(给出具体参数值)
有状态组件:Child对外的类接收属性(定义构造函数),Child对内的类获取属性(使用属性值,widget.参数名)
父组件类(对内类)调用构造函数(给出具体参数值)
3.7.2 子传父

删除图标可以如此写

3.8 网络请求
3.8.1 Dio基本使用
命令安装插件
flutter pub add dio

基本使用: Dio().get(地址).then().catchError()
一般情况下,在初始化状态initState获取页面数据
3.8.2 封装Dio工具

1. 创建工具类DioUtil
连续赋值简写(..),前提:调用函数的主体一致
2. 构造函数中设置基础地址和超时时间

3. 添加各类拦截器
4. 封装统一请求方法

5. 获取数据

6. 解决跨域问题

3.9 路由管理
3.9.1 基本路由

每一个MaterialApp有一套路由系统
3.9.2 命名路由

3.9.3 命名路由传递参数

3.9.4 基本路由传参

3.9.5 高级路由控制

3.9.6 404路由

更多推荐



















所有评论(0)