当前位置:网站首页>flutter系列之:flutter中的IndexedStack
flutter系列之:flutter中的IndexedStack
2022-06-22 01:31:00 【程序那些事】
简介
之前我们介绍了一个flutter的栈结构的layout组件叫做Stack,通过Stack我们可以将一些widget叠放在其他widget之上,从而可以实现图像的组合功能,也是日常中最常用的一种组件了。今天我们要介绍的组件是Stack的近亲,叫做IndexedStack,它有什么功能呢?一起来看看吧。
IndexedStack简介
从名字可以看出,IndexedStack是给Stack添加了一个index的功能,事实是否如此呢?我们先来看一下IndexedStack的定义:
class IndexedStack extends Stack
可以看到IndexedStack继承自Stack,它实际上是Stack的子类,所以之前介绍的Stack有的功能IndexedStack全都有,并且IndexedStack是对Stack的功能进行了增强。
我们来看下它的构造函数:
IndexedStack({
Key? key,
AlignmentGeometry alignment = AlignmentDirectional.topStart,
TextDirection? textDirection,
StackFit sizing = StackFit.loose,
this.index = 0,
List<Widget> children = const <Widget>[],
}) : super(key: key, alignment: alignment, textDirection: textDirection, fit: sizing, children: children);
可以看到和Stack相比,IndexedStack多了一个index参数,但是这个参数并没有传入到super的构造函数中去,那么index到底是在哪里使用的呢?
别急,IndexedStack还重写了下面的两个方法,分别是createRenderObject和updateRenderObject:
@override
RenderIndexedStack createRenderObject(BuildContext context) {
assert(_debugCheckHasDirectionality(context));
return RenderIndexedStack(
index: index,
alignment: alignment,
textDirection: textDirection ?? Directionality.maybeOf(context),
);
}
@override
void updateRenderObject(BuildContext context, RenderIndexedStack renderObject) {
assert(_debugCheckHasDirectionality(context));
renderObject
..index = index
..alignment = alignment
..textDirection = textDirection ?? Directionality.maybeOf(context);
}
和Stack相比,IndexedStack在这两个方法中使用的是RenderIndexedStack,而Stack使用的是RenderStack。
所以虽然IndexedStack继承自Stack,但是两者在表现上是有本质区别的。
对于Stack来说,一个widget被放在另外一个widget之上,但是多个widget可以同时展示出来。而对于IndexedStack来说,它只会展示对应index的widget。
RenderIndexedStack也是继承自RenderStack:
class RenderIndexedStack extends RenderStack
我们看下它的paintStack方法:
@override
void paintStack(PaintingContext context, Offset offset) {
if (firstChild == null || index == null)
return;
final RenderBox child = _childAtIndex();
final StackParentData childParentData = child.parentData! as StackParentData;
context.paintChild(child, childParentData.offset + offset);
}
可以看到在paintStack方法中,只绘制了和index对应的_childAtIndex这个组件,所以如果index不匹配的话,并不会展示出来。
IndexedStack的表现有点像我们常见的tab。
IndexedStack的使用
从上面IndexedStack的构造函数中,我们知道IndexedStack需要传入一个index属性和对应的children。
在本例中,我们给IndexedStack传入一个可变的index属性,和4个child:
IndexedStack(
index: _counter,
children: [
widgetOne(),
widgetTwo(),
widgetThree(),
widgetFour(),
],
)
_counter是定义在StatefulWidget中的变量。可以通过调用setState方法对index进行修改,从而实现动态切换child的目的。
这里的child widget很简单,我们使用了不同大小的SizedBox,SizedBox中设置不同的color来方便观察切换的效果:
Widget widgetOne() {
return SizedBox(
width: 100,
height: 100,
child: Container(
color: Colors.yellow,
),
);
}
最后,在Scaffold的floatingActionButton中调用_changeIndex方法实现index的改变,最终的代码如下:
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _changeIndex() {
setState(() {
_counter = (_counter+1) % 4;
print(_counter);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: IndexedStack(
index: _counter,
children: [
widgetOne(),
widgetTwo(),
widgetThree(),
widgetFour(),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _changeIndex,
tooltip: 'change index',
child: const Icon(Icons.arrow_back),
),
);
}
程序运行之后的效果如下:

通过点击右下方的按钮,我们得到了不同的widget。
总结
IndexWidget和tab有点类似,大家可以在需要的时候使用。
本文的例子:https://github.com/ddean2009/learn-flutter.git
更多内容请参考 www.flydean.com
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
边栏推荐
- Redis缓存异常及处理方案总结
- 2021 csp-j1 csp-s1 first round preliminary round related questions and videos
- BSV上的委托合约
- 英特尔发展史概述
- [bit operation] leetcode1009 Complement of Base 10 Integer
- Apache Doris real-time data analysis nanny level tutorial
- shadertoy 实现简易指南针
- NOIP初赛 CSP-J1 CSP-S1 第1轮 初赛 信奥中的数学知识(一)
- 内网学习笔记(9)
- acwing 837. Number of points in connected blocks (additional information maintained by querying sets - number of sets)
猜你喜欢

Packet capturing tool: Fiddler, a necessary skill for Software Test Engineer

DAST 黑盒漏洞扫描器 第四篇:扫描性能

第八届“互联网+”大赛|百度杰出架构师毕然解读产业赛道命题

初识Unity3D(项目结构、ProBuilder第三方插件)

Rational rose 安装教程

技术探秘: 360数科夺得ICDAR OCR竞赛世界第一

【Proteus仿真】INT0和INT1中断计数

【第 06 章 MATLAB实现基于分水岭分割进行肺癌诊断】

Appium面试题

The Sandbox 与《时代周刊》达成合作,在元宇宙建立“纽约时报广场”
随机推荐
The way to build the efficiency platform of didi project
[number theory] leetcode1010 Pairs of Songs With Total Durations Divisible by 60
Commission contract on BSV (2)
【数论】leetcode1010. Pairs of Songs With Total Durations Divisible by 60
第 21 章 路面裂缝检测识别系统设计--matlab深度学习实战
Seeking an anti association detection tool, online detection of browser fingerprint
NOIP初赛 CSP-J1 CSP-S1 第1轮 初赛 信奥中的数学知识(一)
第 18 章 基于GUI搭建通用视频处理工具matlab应用GUI实现
【第 07 章 基于主成分分析的人脸二维码识别MATLAB深度学习实战案例】
Mathematical knowledge in the first round of noip preliminary round csp-j1 csp-s1 Sinorgchem (III)
acwing 837. 连通块中点的数量 (并查集维护额外信息---集合数量)
[Chapter 10: a website digital verification code recognition based on moment invariants matlab deep learning practical application case]
阿里,腾讯,百度软件测试工程师推荐——软件测试模型之瀑布模型
初识Unity3D(项目结构、ProBuilder第三方插件)
LocalDateTime格式化时间
2019 csp-j1 csp-s1 first round preliminary round answer analysis and summary, video, etc
Amazon evaluation browser, core knowledge points of Amazon evaluation risk control
Leetcode + 46 - 50
Mathematical knowledge of Sinorgchem in the first round of noip preliminary csp-j1 csp-s1 (I)
Preliminary competition of noip improvement group III. problem solving exercise set noip1995-noip2018