Flutter - 布局
MaterialApp包裹整个应用形成统一的Material Design风格Scoffold组件可以快速搭建页面骨架,如appBar,body,bottomNavigationBar等Container用来作为容器,设置高度(height),child用来存放子组件Text是用来显示文本的组件根据自己的特点的需求创建自己的widget创建一个新的类,继承StatelessWidget类并实现bu
目录
常用滚动组件 - SingleChildScrollView
Flutter -- 基础组件MaterialApp
特性:
整个应用被MaterialApp包裹,方便对整个应用进行整体设计
常见属性:
- title:用来展示窗口的标题内容
- theme:用来设置整个应用的主题
- home:用来展示窗口的主体内容
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(scaffoldBackgroundColor: Colors.blue),
home: Scaffold(),
));
}
基础组件 - Scaffold组件
Scaffold:用于构建Material Design风格页面的核心布局组件,提供标准,灵活配置的页面骨架
|
属性 |
主要作用说明 |
|
appBar |
页面顶部的应用栏,通常用于显示标题、导航按钮和操作菜单 |
|
body |
页面的主要内容区域,可以放置任何其他组件,是页面的核心 |
|
bottomNavigationBar |
底部导航栏,方便用户在不同核心功能页面间切换 |
|
backgroundColor |
设置整个 Scaffold 的背景颜色 |
|
floatingActionButton |
悬浮操作按钮,常用于触发页面的主要动作 |
|
... |
其他 |

import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MaterialApp(
title: 'Flutter Demo',
// theme: ThemeData(scaffoldBackgroundColor: Colors.blue),
home: Scaffold(
appBar: AppBar(
title: Center(
child: Text("头部区域"),
),
),
body: Container(
child: Center(
child: Text("中部区域"),
),
),
bottomNavigationBar: Container(
height: 80.3,
child: Center(
child: Text("底部区域"),
),
),
),
));
}
总结:
- MaterialApp包裹整个应用形成统一的Material Design风格
- Scoffold组件可以快速搭建页面骨架,如appBar,body,bottomNavigationBar等
- Container用来作为容器,设置高度(height),child用来存放子组件
- Text是用来显示文本的组件
Flutter自定义组件 - 无状态组件和有状态组件
定义:
根据自己的特点的需求创建自己的widget
分类:
- 无状态组件
- 有状态组件
|
特性 |
StatelessWidget(无状态) |
StatefulWidget(有状态) |
|
核心特征 |
一旦创建,内部状态不可变 |
持有可在其生命周期内改变的状态 |
|
使用场景 |
静态内容展示,外观仅由配置参数决定 |
交互式组件,如计数器、可切换开关、表单输入框 |
|
生命周期 |
相对简单,主要是构建(build) |
更为复杂,包含状态创建、更新和销毁 |
|
代码结构 |
单个类 |
两个关联的类:Widget本身和单独的State类 |
无状态组件 - StatelessWidget
定义:
创建一个新的类,继承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: "Flutter初体验-无状态组件",
home: Scaffold(
appBar: AppBar(
title: Text("头部区域"),
),
body: Container(
child: Center(
child: Text("中部区域"),
),
),
bottomNavigationBar: Container(
height: 80,
child: Center(
child: Text("底部区域"),
),
)),
);
}
}
有状态组件 - StatefulWidget
定义:
有状态组件是构建动态交互界面的核心,能够管理变化的内部状态,当状态改变时,组件会更新显示内容
实现1:
创建两个类,第一个类继承StatefulWidget类,主要接收和定义最终参数,核心作用是创建State对象
实现2:
第二个类继承State<第一个类名>,负责管理所有可变的数据和业务逻辑,并实现build构建方法
要点:
build方法需要返回一Widget
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
// 第一个类 有状态组件
class MainPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MainPageState();
}
}
// 第二个类 内部类 负责管理数据 处理业务逻辑 并且渲染视图
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter初体验-有状态组件",
home: Scaffold(
appBar: AppBar(
title: Text("头部区域"),
),
body: Container(
child: Center(
child: Text("中部区域"),
),
),
bottomNavigationBar: Container(
height: 80,
child: Center(
child: Text("底部区域"),
),
)),
);
}
}
总结:


快捷键创建组件:
- stl - 无状态组件
- stf - 有状态组件
组件生命周期 - 无状态组件
- 无状态组件 - 唯一阶段
- 当组件被创建或父组件状态变化导致其重新构建时,build方法会被重新调用
build方法会被重新执行
组件生命周期 - 有状态组件
- 创建阶段
- 更新阶段
- 销毁阶段

|
生命周期阶段 |
函数名 |
调用时机与核心任务 |
|
创建阶段 |
createState() |
Widget初始化调用,创建State对象 |
|
initState() |
State对象插入Widget树立刻执行,仅执行一次 |
|
|
didChangeDependencies() |
initState后立刻执行,当所依赖的InheritedWidget更新时调用,可能多次 |
|
|
构建与更新阶段 |
build() |
构建UI方法,初始化或更新后多次调用 |
|
didUpdateWidget() |
父组件传入新配置时调用,用于比较新旧配置 |
|
|
销毁阶段 |
deactivate() |
当State对象从树中暂时移除时调用 |
|
dispose() |
当State对象被永久移除时调用,释放资源,仅执行一次 |
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() {
print("createState阶段");
return _MainPageState();
}
}
class _MainPageState extends State<MainPage> {
@override
void initState() {
print("initState阶段执行");
// TODO: implement initState
super.initState();
}
// didChangeDependencies
@override
void didChangeDependencies() {
print("didChangeDependence");
super.didChangeDependencies();
}
// didUpdateWidget
@override
void didUpdateWidget(covariant MainPage oldWidget) {
print("didUpdateWidget阶段执行");
super.didUpdateWidget(oldWidget);
}
// deactivate
@override
void deactivate() {
print("deactivatet阶段执行");
super.deactivate();
}
// deactivate
@override
void dispose() {
print("dispose阶段执行");
super.dispose();
}
@override
Widget build(BuildContext context) {
print("build阶段");
return Container(
child: null,
);
}
}
总结:
- 无状态组件 - build
- 有状态组件(创建阶段):createState -> initState -> didChangeDependencies -> build
- 有状态组件(更新阶段):didUpdateWidget -> build
- 有状态组件(销毁阶段):deactivate -> dispose
- 执行一次函数:createState,initState,dispose
- inheritedWidget:专门用于在Widget树中自顶向下高效地共享数据,顶层组件提供数据,子孙节点直接获取
事件 - 点击事件GestureDetector
- 事件:各种动作
- 点击事件:当点击某个元素触发地动作
- 常规方案:GestureDetector是Flutter常用,功能最丰富的手势检测组件
- 方法:使用GestureDetector包裹被点击的元素,传入onTab方法
body: Container(
child: Center(
child: GestureDetector(
onDoubleTap: () => print("双击了该区域"),
// 点击事件
onTap: () => print("点击了该区域"),
child: Text("中部区域"),
),
),
),
事件 - 组件点击事件
组件:Flutter提供了多种方式为组件添加点击交互
|
组件类别 |
核心组件 |
主要特点/使用场景 |
|
专用按钮组件 |
ElevatedButton、TextButton、OutlineButton、FloatingActionButton |
内置点击动画和样式,通过 onPressed 参数处理点击逻辑 |
|
视觉反馈组件 |
InkWell |
提供点击事件(onTap),有 Material Design 风格的水纹扩散效果 |
|
其他交互组件 |
IconButton、Switch、Checkbox |
具有特定功能的交互式控件,支持点击事件(onPressed) |
body: Container(
child: Center(
child: TextButton(onPressed: () {
print("按钮的点击事件");
}, child: Text("按钮"))
),
),
状态更新 - setState
语法:
数据的变化更新UI视图,需要执行setState方法,setState方法会造成build的重新执行
案例:
实现一个计数器案列
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
// 有状态组件
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int count = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Row(
children: [
TextButton(
onPressed: () {
setState(() {
count -= 1;
});
},
child: Text("减")),
Text(count.toString()),
TextButton(
onPressed: () {
setState(() {
count += 1;
});
},
child: Text("加")),
],
),
)),
);
}
}
布局组件:

基础容器 - Container
定义:
Container是功能丰富的布局组件,是一个多功能组合容器
尺寸控制:
可通过多种方式定义大小
优先级:
明确宽高 > constraints约束 > 父组件约束 > 自适应大小
装饰系统:
通过decoration属性实现视觉效果,但和color属性互斥
布局控制:
提供内外边距和对齐方式
可选变化:
支持绘制时进行矩阵变化。
常见属性:

import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
alignment: Alignment.center,
margin: EdgeInsets.all(50),
width: 200,
height: 200,
transform:Matrix4.rotationZ(0.05), // 弧度 而非角度
// color: Colors.blue,
decoration: BoxDecoration(
border: Border.all(width: 3,color: Colors.yellow),
color: Colors.blue, borderRadius: BorderRadius.circular(15)),
child: Text(
"Hello ,Container",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
)),
);
}
}
基础容器 - Center - 居中组件
Center:将其子组件在父容器的空间内进行水平和垂直方向上的居中排列
应用场景:页面内容整体居中,如登陆表单
注意事项:Cneter不能设置宽高,Center的最终大小取决于其父组件传递给它的约束,Center会向它的父组件申请可能大的空间
实现固定高度且居中的组件:Center去包裹一个具有固定宽高的子组件。Container/SizeBox
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Center代码示例"),
),
body: Center(
child:Container(
alignment: Alignment.center,
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.blue
),
child: Text("居中内容",style: TextStyle(color: Colors.white)),
)
)),
);
}
}
基础容器 - Align - 对齐组件
作用:精确控制其子组件在父容器空间内的对齐位置
alignment(对齐方式):子组件在父容器内的对齐方式
widthFactor(宽度因子):Align的宽度将是子组件宽度乘以该因子
heightFactor(高度因子):Align的高度将是子组件高度乘以该因子
与Center组件的区别:Center是Align的一个特例
使用场景:当需要将一个组件放置在父容器的特定角落,Align是理想选择。
动态尺寸:通过widthFactor和heightFactor,可以创建出与子组件大小成比例的容器,动态布局很有用。
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Align代码示例"),
),
body: Align(
alignment: Alignment.center,
widthFactor: 1,
heightFactor: 1,
child: Icon(Icons.star, size: 120, color: Colors.amber),
)),
);
}
}
基础组件 - Padding - 内边距组件
作用:为其子组件添加内边距



线性布局 - Column.
Column不支持宽高,是子组件撑开的
作用:
用于垂直排列其子组件的核心布局容器

- 设置主轴

- 交叉轴

- 使用场景:

import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Align代码示例"),
),
body: Container(
width: double.infinity, // 正无穷大
height: double.infinity, // 正无穷大
decoration: BoxDecoration(color: Colors.amber),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(bottom: 10),
color: Colors.blue,
),
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(bottom: 10),
color: Colors.blue,
),
Container(
width: 100,
height: 100,
color: Colors.blue,
)
],
),
)),
);
}
}
线性布局 - Row
作用:
用于水平排列其子组件的核心布局容器


弹性布局 - Flex
作用:
允许一个主轴(水平或垂直)排列其子组件,灵活控制这些子组件在主轴上的尺寸比列和空间分配

子组件:
Flex的子组件常用Expanded或Flexible来控制空间分配
弹性布局 - Flex/Expanded/Flexible
- Expanded/flexible作为Flex的子组件通过flex属性来分配Flex组件空间
Flex(
direction: Axis.horizontal,
children: [
Expanded(
flex: 2,
child: Container(
width: 100,
height: 100,
color: Colors.blue,
)),
Expanded(
flex: 1,
child: Container(
width: 100,
height: 100,
color: Colors.red,
)),
Expanded(
flex:1,
child: Container(
width: 100,
height: 100,
color: Colors.green,
))
],
),
常用Expanded组件
- Flex布局受其父组件传递的约束影。确保父组件提供了适当的布局约束
- Expanded与Flexible的区别:Expanded强制子组件填满所有剩余空间,Flexible根据自身大小调整,不强制沾满空间。
Flex实例:

import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Flex代码示例"),
),
body: Container(
color: Colors.amber,
child: Flex(
direction: Axis.vertical,
children: [
Container(
color: Colors.blue,
height: 100,
),
Expanded(child:
Container(color: Colors.grey),
),
Container(
height: 100,
color: Colors.red,
)
],
),
)),
);
}
}
流失布局 - Wrap
作用:
流式布局组件,当子组件在主轴方向上排列不下时,他会自动换行(或换列)

Column/Row/Flex内容超过不会换行
Wrap组件更像是Flex组件加了换行
场景:
- 当子组件内容是根据数据动态生成时,使用wrap可以确保布局始终适配

import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatelessWidget {
const MainPage({super.key});
List<Widget> getLsit() {
return List.generate(10, (index) {
return Container(
color: Colors.blue,
width: 100,
height: 100,
);
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Wrap代码示例"),
),
body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Wrap(
spacing: 10,
runSpacing: 10,
alignment: WrapAlignment.center,
direction: Axis.horizontal,
children: getLsit(),
))),
);
}
}

层叠布局 - Stack/Positioned
作用:
层叠布局组件,允许你将多个子组件按照Z轴(深度方向)进行叠加排列

搭档:
Positioned组件时Stack的黄金搭档,对子组件进行精确定位控制。Positioned必须作为Stack的直接子组件
Positioned通过left,right,top,bottom来将子组件“钉”在Stack的某个角落或边缘
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Stack代码示例"),
),
body: Stack(
alignment: AlignmentDirectional.center,
children: [
Container(
width: 300,
height: 300,
color: Colors.blue,
),
Container(
width: 200,
height: 200,
color: Colors.red,
),
Container(
width: 100,
height: 100,
color: Colors.green,
)
],
)),
);
}
Positioned(
left:0,
bottom:0,
child:Container(
width:100,
height:100,
color:Colors.blue
)
)
Positioned必须搭配Stack

Stack中子组件的层叠顺序由其在children列表中的顺序决定
明确尺寸约束,父组件的大小直接影响Stack的最终大小和子组件的布局行为
文本组件 - Text
作用:
在用户界面中显示文本的基础组件

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Stack代码示例"),
),
body: Container(
alignment: AlignmentDirectional.center,
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Text("Hello Flutter",
style: TextStyle(
fontSize: 30,
color: Colors.blue,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
decorationColor: Colors.red
)),
)),
);
}
文本组件 - Text/TextSpan
如果需要在同一段文本中显示不同样式,可用Text.rich构造函数配合TextSpan来实现
child: Text.rich(
TextSpan(
text: "HELLO ",
children: [TextSpan(text: "FLUTTER",style: TextStyle(color: Colors.green))],
style: TextStyle(
color: Colors.red,
fontSize: 40,
fontWeight: FontWeight.bold)
)
),

Text组件本身和TextStyle中都可能有overflow等属性,Text组件属性优先级更高
假如文本过长请务必设置maxLines和overflow
大量重复使用文本样式,建议统一定义
图片组件 - Image
作用:
在用户界面中显示图片的核心部件
图片分类:


步骤:
- 配置pubspec.yaml文件
- 打开assets选项
- 注意缩近格式
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Text代码示例"),
),
body: Container(
alignment: AlignmentDirectional.center,
width: double.infinity,
height: double.infinity,
color: Colors.amber,
child: Image.asset("lib/images/Myteam.png",width: 100,height: 100,fit: BoxFit.cover,),
)),
);
}
Image.network 网络图片

Android/ios使用image.network需要配置网络权限
文本输入组件 - TextField
作用:
实现文本输入功能的核心组件

- 使用有状态组件
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
TextEditingController _accountController = TextEditingController();
TextEditingController _PassWordController = TextEditingController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("登录")),
body: Container(
padding: EdgeInsets.all(20),
color: Colors.white,
child: Column(
children: [
TextField(
onChanged: (value){
print(value);
},
onSubmitted: (value) {
print(value);
},
controller: _accountController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 20),
// 内容内边距
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(25)),
hintText: "请输入账号",
fillColor: Colors.amber,
filled: true),
),
SizedBox(height: 20),
TextField(
controller: _PassWordController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 20),
// 内容内边距
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(25)),
hintText: "请输入密码",
fillColor: Colors.amber,
filled: true),
obscureText: true),
SizedBox(height: 20),
Container(
width: double.infinity,
height: 50,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(25)),
child: TextButton(
onPressed: () {
print("登录${_accountController.text} - ${_PassWordController.text}");
},
child: Text(
"登录",
style: TextStyle(color: Colors.white),
)),
)
],
),
),
),
);
}
}
- 使用TextField必须使用有状态组件
- decoration属性下的InputDecoration来定制
- obsureText设置true可隐藏输入内容,用于密码输入框
常用滚动组件

常用滚动组件 - SingleChildScrollView
用法:包裹一个子组件,让单个子组件具备滚动能力
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("登录")),
body: SingleChildScrollView(
padding: EdgeInsets.all(20),
child: Column(
children: List.generate(100, (index) {
return Container(
margin: EdgeInsets.only(top: 10),
color: Colors.blue,
height: 100,
width: double.infinity,
alignment: Alignment.center,
child: Text('我是第${index + 1}个',
style: TextStyle(color: Colors.white, fontSize: 30)),
);
}),
)
),
),
);
}
控制滚动 - SingleChildScrollView
controller:给组件的controller绑定ScrollController对象

- 子组件:
只能包含一个子组件,如果滚动多个组件,通常将其嵌套在Column或Row中
滚动方向:通过scrollDirection属性控制,默认为垂直方向,也可设置水平方向
- 特点:
一次性构建所有子组件,如果嵌套Column或Row中包含大量子项,可能会导致性能问题,建议使用ListView
- 控制滚动:
绑定一个ScrollController对象给controller对象,使用animateTo/JumpTo方法控制滚动
- 滚动到顶部:
conroller.jumpTo(0)
- 滚动到底部:
controller.jumpTo(contr.position.maxScrollExtent)
常用滚动组件 - ListView
作用:用于构建可滚动列表的核心不见,并提供流畅滚动体验
方式:提供多种构造函数,如默认构造函数,ListView.builder、ListView.separated
机制:采用按需渲染(懒加载),之构建当前可见区域的列表项,极大提升列表性能
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("登录")),
body: ListView(
children: List.generate(100, (index) {
return Container(
color: Colors.blue,
width: double.infinity,
height: 80,
margin: EdgeInsets.only(top: 10),
alignment: Alignment.center,
child: Text("第${index + 1}个",
style: TextStyle(color: Colors.white)),
);
}))));
}
ListView - builder模式
作用:
处理长列表或动态数据的首选和推荐方式
方式:
接受一个itemBuilder回调函数来按需构建列表项,通过itemCount控制列表长度

ListView - separate模式
作用:
在ListView.builder的基础上,额外提供了构建分割线的能力
方式:
需要同时提供itemBuilder、separatorBuilder、itemCount三个属性
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("登录")),
body: ListView.separated(itemBuilder: (BuildContext context,int index){
return Container(
// margin: EdgeInsets.only(top: 10),
color:Colors.blue,
width: double.infinity,
height: 80,
child: Text("第${index + 1}个",style: TextStyle(color: Colors.white,fontSize: 30)),
alignment: Alignment.center,
);
}, separatorBuilder: (BuildContext context,int index) {
return Container(
height: 10,
width: double.infinity,
color:Colors.yellow,
);
}, itemCount: 100),
));
}
常用滚动组件 - GridView
作用:
用于创建二维可滚动网格布局的核心组件
方式:
提供多种构建方式,GridView.count,GridView.extent,GridView.builder




自定义滚动容器 - CustomScrollView
作用:
用于组合多个可滚动组件(列表,网格),实现统一协调的滚动效果
Sliver:
Flutter中描述可滚动视图内部一部分内容的组件,他是滚动视图的切片
用法:
通过Slivers属性接受一个Sliver组件列表
Sliver组件对应关系:

import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("登录")),
body: CustomScrollView(
slivers: [
// 包裹普通widget组件
SliverToBoxAdapter(
child: Container(
width: double.infinity,
height: 260,
color: Colors.blue,
child: Text("轮播图",
style: TextStyle(color: Colors.white, fontSize: 30)),
alignment: Alignment.center,
),
),
SliverToBoxAdapter(
child: SizedBox(
height: 10,
),
),
SliverPersistentHeader(
delegate: _StickyCategory(), pinned: true),
SliverToBoxAdapter(
child: SizedBox(
height: 10,
),
),
// 双列排序
SliverGrid.count(crossAxisCount: 2,crossAxisSpacing: 10,mainAxisSpacing: 10,children:List.generate(100, (index){
return Container(
color: Colors.blue,
alignment: Alignment.center,
child: Text("列表项${index + 1}",style: TextStyle(color: Colors.white,fontSize: 20),),
);
}))
// 单列排序
// SliverList.separated(
// itemBuilder: (BuildContext context, int index) {
// return Container(
// color: Colors.blue,
// height: 100,
// alignment: Alignment.center,
// child: Text("列表项${index + 1}",style: TextStyle(color: Colors.white,fontSize: 20)),
// );
// },
// separatorBuilder: (BuildContext context, int index) {
// return SizedBox(
// height: 20,
// );
// })
],
)));
}
}
class _StickyCategory extends SliverPersistentHeaderDelegate {
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
color: Colors.white,
child: ListView.builder(
itemCount: 30,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
return Container(
width: 100,
margin: EdgeInsets.symmetric(horizontal: 10),
alignment: Alignment.center,
color: Colors.blue,
child: Text("分类:${index + 1}",
style: TextStyle(color: Colors.white)),
);
}),
);
}
@override
// 最大展开去高度
double get maxExtent => 80;
@override
// 最小折叠高度
double get minExtent => 60;
@override
// 是否需要重建
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
// TODO: implement shouldRebuild
return false;
}
}



整页滚动容器 - PageView
作用:
用于实现分页滚动视图的核心组件
方式:
提供多种构建方式,默认构造方式、PageView.builder等
优势:
支持懒加载(按需渲染)

控制器:PageView绑定controller属性,对象类型为PageController
切换方法:controller.jumpPage、animateToPage

更多推荐



所有评论(0)