Flutter解析子树中共享同一标签的多个英雄

时间:2020-10-30 17:22:17

标签: flutter

在移动应用程序的简单部分中,我毫无问题地使用了Hero,并且工作正常,现在,当我尝试添加一个名为Widget的类作为AnimatedFab时,我收到这个错误:

在子树中有多个共享相同标签的英雄。

我在此类中没有使用任何Hero,我想知道为什么会收到错误消息

我在Hero中使用了Stack,实现代码为:

Positioned(
    top: 259.0,
    left: 6.0,
    child:  SizedBox(
      key: _imageKey,
      width: 43.0,
      height: 43.0,
      child: InkWell(onTap: () {
        //...
      },child: MyHero(hiveFeed: widget.hiveFeeds)),
    )),

Stack的父级中,上面的代码是该子级的一个子代,我有以下代码:

Positioned(top: 140.0, right: -40.0, child: const AnimatedFab().pl(8.0)),

完整的Stack个孩子:

return Stack(
    children: [
        Card(
          child: Stack(
            children: [
              Positioned(top: 140.0, right: -40.0, child: const AnimatedFab().pl(8.0)),
            ],
          ),
        ),
        Positioned(
            top: 259.0,
            left: 6.0,
            child:  SizedBox(
              key: _imageKey,
              width: 43.0,
              height: 43.0,
              child: InkWell(onTap: () {
                //...
              },child: MyHero(hiveFeed: widget.hiveFeeds)),
            )),
  ],
);

已更新

我将heroTag视为以下类中的值:

我对此有问题的

AnimatedFab类是下面的代码:


Positioned(top: 140.0, right: -40.0, child: AnimatedFab(key:_imageKey).pl(8.0)),


class AnimatedFab extends StatefulWidget {
  final VoidCallback onPressed;
  final Key _key;
  const AnimatedFab({Key key, this.onPressed}) : _key = key;

  @override
  _AnimatedFabState createState() => _AnimatedFabState();
}

class _AnimatedFabState extends State<AnimatedFab> with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation<Color> _colorAnimation;

  final double expandedSize = 160.0;
  final double hiddenSize = 50.0;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(vsync: this, duration: const Duration(milliseconds: 200));
    _colorAnimation = ColorTween(begin: Colors.transparent, end: Colors.pink[800]).animate(_animationController);
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: expandedSize,
      height: expandedSize,
      child: AnimatedBuilder(
        animation: _animationController,
        builder: (BuildContext context, Widget child) {
          return Stack(
            alignment: Alignment.center,
            children: <Widget>[
              _buildFabCore(widget.key),
            ],
          );
        },
      ),
    );
  }

  Widget _buildOption(IconData icon, double angle) {
    if (_animationController.isDismissed) {
      return Container();
    }
    double iconSize = 0.0;
    if (_animationController.value > 0.8) {
      iconSize = 26.0 * (_animationController.value - 0.8) * 5;
    }
    return Transform.rotate(
      angle: angle,
      child: Align(
        alignment: Alignment.topCenter,
        child: Padding(
          padding: const EdgeInsets.only(top: 8.0),
          child: IconButton(
            onPressed: _onIconClick,
            icon: Transform.rotate(
              angle: -angle,
              child: Icon(
                icon,
                color: Colors.black54,
              ),
            ),
            iconSize: iconSize,
            alignment: Alignment.center,
            padding: const EdgeInsets.all(0.0),
          ),
        ),
      ),
    );
  }

  Widget _buildExpandedBackground() {
    final double size = hiddenSize + (expandedSize - hiddenSize) * _animationController.value;
    return AnimatedOpacity(
      opacity: _animationController.value,
      duration: const Duration(milliseconds: 300),
      child: Card(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(100.0)),
        elevation: 4.0,
        child: Container(
          height: size,
          width: size,
        ),
      ),
    );
  }

  Widget _buildFabCore(Key key) {
    final double scaleFactor = 2 * (_animationController.value - 0.5).abs();
    return FloatingActionButton(
      key: key,
      elevation: 0.0,
      mini: true,
      onPressed: _onFabTap,
      backgroundColor: _colorAnimation.value,
      child:  Transform(
        alignment: Alignment.center,
        transform:  Matrix4.identity()..scale(1.0, scaleFactor),
        child:  Icon(
          _animationController.value > 0.5 ? Icons.close : Icons.filter_list,
          color: _animationController.value > 0.5 ? Colors.white:Colors.black54,
          size: 26.0,
        ),
      ),
    );
  }

  void open() {
    if (_animationController.isDismissed) {
      _animationController.forward();
    }
  }

  void close() {
    if (_animationController.isCompleted) {
      _animationController.reverse();
    }
  }

  void _onFabTap() {
    if (_animationController.isDismissed) {
      open();
    } else {
      close();
    }
  }

  void _onIconClick() {
    widget.onPressed();
    close();
  }
}

我该如何解决这个问题?我认为主要问题是在_buildFabCore(),中,我在此类中有此方法。

预先感谢

1 个答案:

答案 0 :(得分:0)

考虑在heroTag内将FloatingActionButton的值传递给_buildFabCore或直接传递null
如果您在应用程序中使用了另一个FloatingActionButton,则可能会发生这种情况,因此,如果您没有为每个变量传递不同的heroTag,则会收到此错误。