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

4次阅读

共计 3328 个字符,预计需要花费 9 分钟才能阅读完成。

简介

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

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

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

正文完
 0