如何在 Flutter 中将 Hero 动画添加到我的 ListView?

Posted

技术标签:

【中文标题】如何在 Flutter 中将 Hero 动画添加到我的 ListView?【英文标题】:How to add Hero animations to my ListView in Flutter? 【发布时间】:2020-10-28 20:19:18 【问题描述】:

我有一个 ListView,其中包含如下所示的卡片。我正在尝试使卡片在被按下时以更大的尺寸打开。

我已经为一张卡片实现了这一点,但是我不明白如何为 ListView 做到这一点。在 ListView 元素上添加 Hero 标签后,我收到以下错误:

There are multiple heroes that share the same tag within a subtree.

这是animation。

这是动画的代码:

第一页:

  Widget build(BuildContext context) 
    return new Scaffold(
      body: Hero(
          tag: 'flutterLogo',
          child: GestureDetector(
            onTap: () => Navigator.push(context,
                MaterialPageRoute(builder: (context) => AnimatedPage())),
            child: Card(
              elevation: 4.0,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12.0),
              ),
              child: Container(
                height: 180,
                width: 300,
                color: Colors.blue,
              ),
            ),
          )),
    );
  

第二页:

  Widget build(BuildContext context) 
    return new Scaffold(
      body: Stack(
        children: <Widget>[
          Hero(
            tag: 'flutterLogo',
            child: Padding(
              padding: const EdgeInsets.only(top: 20.0),
              child: Card(
                elevation: 4.0,
                color: Colors.red,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(12.0),
                ),
                child: Container(
                  height: 200,
                  width: 300,
                  child: Center(child: Text('Hello')),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  

这是我的 ListView 的代码:

 SliverList(
        delegate: SliverChildBuilderDelegate(
          (BuildContext context, int index) 
            return Hero(
              tag: 'flutterLogo',
              child: Padding(
                padding: const EdgeInsets.only(top: 10.0, bottom: 10),
                child: GestureDetector(
                  onTap: () 
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) => PaymentPage()));
                  ,
                  child: Card(
                    elevation: 4.0,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12.0),
                    ),
                    child: Container(
                      height: 180,
                      width: 150,
                    ),
                  ),
                ),
              ),
            );
          ,
          childCount: 4,
        ),
      ),

这就是列表的样子:

我正在尝试打开相同的 第二页如动画所示,点击列表中的卡片后。

【问题讨论】:

这能回答你的问题吗? There are multiple heroes that share the same tag within a subtree 我看到了这个但是我不明白如何在我的情况下实现这个@NileshRathod 引用@NileshRathod 的链接,您可以这样做,在SliverList 中使用tag: 'flutterLogo$index' 并修改SecondPage 以将tag 作为参数,如PaymentPage('flutterLogo$index') 和在 SecondPage 上的 Hero 小部件中使用它 【参考方案1】:

英雄标签应该不同,所以在你的SliverList中把你的标签改成这样:

tag: 'flutterLogo$index',

并将标签传递到您的第二页,如下所示(如果它是StatefulWidget):

class SecondPage extends StatefulWidget 
  final String heroTag;
  SecondPage(Key key, this.heroTag) : super(key: key);

  @override
  _SecondPageState createState() => _SecondPageState();

然后不要在第二页中使用简单的标签,而是使用如下内容:

tag: widget.heroTag,

【讨论】:

以上是关于如何在 Flutter 中将 Hero 动画添加到我的 ListView?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中使用 Hero 转换期间未运行的动画/动画?

Flutter动画

Flutter Hero 动画

禁用 Flutter Hero 反向动画

列表视图项之间的 Flutter Hero 类似动画

Flutter - 我可以用 Hero 包装每个小部件来为它们设置动画吗