这段错误信息描述通常如下:‘Within each subtree for which heroes are to be animated (i.e. a PageRoute subtree), each Hero must have a unique non-null tag. In this case, multiple heroes had the following tag:
首先得知道Hero是Flutter中的一种动画形式,两个带有同样hero标识的元素在页面切换时会有一个飞动的效果,该效果由flutter自动实现。该标识对应的属性名为heroTag,在同一个页面内,每个heroTag只能拥有一个独一无二的值(和html种的id一样),如果重复就会抛出标题所示的异常‘There are multiple heroes that share the same tag within a subtree.’。解决办法自然是修改重复的heroTag值即可。
例如,FloatingActionButton就是自带的Hero动画的按钮元素,阅读源码可以发现,它的参数定义:
const FloatingActionButton({
Key key,
this.child,
this.tooltip,
this.foregroundColor,
this.backgroundColor,
this.focusColor,
this.hoverColor,
this.splashColor,
this.heroTag = const _DefaultHeroTag(),
this.elevation,
this.focusElevation,
this.hoverElevation,
this.highlightElevation,
this.disabledElevation,
@required this.onPressed,
this.mini = false,
this.shape,
this.clipBehavior = Clip.none,
this.focusNode,
this.autofocus = false,
this.materialTapTargetSize,
this.isExtended = false,
})
heroTag的值默认被初始化为,一个常量const _DefaultHeroTag(),该常量定义为:
class _DefaultHeroTag {
const _DefaultHeroTag();
@override
String toString() => '';
}
所以当我们在一个页面种使用两个FloatingActionButton却不覆写它们的heroTag属性,它们会默认使用同一个标识,以致于冲突报错。同时,_DefaultHeroTag的toString方法返回‘
所以我们只需要修改一个FloatingActionButton的heroTag,让它不再是默认值即可:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: navigatorBar(context,title: 'xxx'),
floatingActionButton: FloatingActionButton(
onPressed: null,
tooltip: 'Increment',
child: Icon(Icons.add),
heroTag: 'other',
), // This trailing comma makes auto-formatting nicer for build methods.
);
}