简介
之前咱们介绍了一个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
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」,懂技术,更懂你!
发表回复