关于flutter:flutter系列之flutter中可以建索引的栈布局IndexedStack

简介

之前咱们介绍了一个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

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」,懂技术,更懂你!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理