簡體   English   中英

禁用 Flutter Hero 反向動畫

[英]Disabling Flutter Hero reverse animation

給定 2 個路由,例如父級和子級以及具有相同標簽的 Hero(..) 小部件。 當用戶在“父”屏幕上並打開一個“子”時 - 英雄小部件是動畫的。 當它返回時(通過Navigator.pop )它也是動畫的。

我正在尋找一種在返回時禁用該動畫的方法(通過Navigator.pop從孩子到父母)。

是否有一種處理程序會在小部件被“動畫化”之前被調用? 然后我可能可以更改Hero標簽並解決問題。

或者,在為父小部件中的路線創建“構建器”時,我可能記得對目標小部件的引用,並在調用Navigator.pop之前通知它“你將被動畫化”。 這還需要使該小部件有狀態(我還沒有找到強制重建無狀態小部件的方法)。

有沒有更簡單的方法來實現這個?

雖然目前沒有內置的方法可以禁用任何特定方向的 Hero 動畫,盡管 CLucera 使用FadeTransitionHeroFlightDirection是一種創造性的方式,但最直接的方法是打破兩個 Hero 之間的tag關聯:

當您從第 2 個英雄返回到第 1 個英雄時,只需將第 1 個英雄的標簽暫時更改為其他內容,則該英雄將不會返回動畫。 一個簡化的例子:

class _MyHomePageState extends State<MyHomePage> {

  String tag1, tag2;
  String sharedTag = 'test';
  String breakTag = 'notTest';

  @override
  void initState() {
    super.initState();
    tag1 = sharedTag;
    tag2 = sharedTag;
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Hero(
            tag: tag1,
            child: RaisedButton(
              child: Text("hi"),
              onPressed: () {
                // restore the tag
                if (tag1 != sharedTag) {
                  setState(() {
                    tag1 = sharedTag;
                  });
                }

                // second route
                Navigator.of(context).push(
                    MaterialPageRoute<void>(
                        builder: (BuildContext context) {
                          return Scaffold(
                            appBar: AppBar(
                              title: Text(widget.title),
                            ),
                            body: Container(
                                alignment: Alignment.topLeft,
                                child: Hero(
                                  tag: tag2,
                                  child: RaisedButton(
                                    child: Text('hello'),
                                    onPressed: () {
                                      // change the tag to disable the reverse anim
                                      setState(() {
                                        tag1 = breakTag;
                                      });

                                      Navigator.of(context).pop();
                                    },
                                  ),
                                )
                            ),
                          );
                        }
                    )
                );
              },
            )
        ),
      ),
    );
  }
}

但是如果你想直接修改動畫,那么在flightShuttleBuilder里面flightShuttleBuilder是像 CLucera 那樣做的方法。 您還可以查看媒體/掌握英雄動畫在顫動以進一步探索該領域。

目前我能想到的唯一方法是以一種似乎沒有動畫的方式“動畫”彈出的英雄,讓我們檢查一下這段代碼:

class SecondRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Hero(
          flightShuttleBuilder: (context, anim, direction, fromContext, toContext) {
            final Hero toHero = toContext.widget;
            if (direction == HeroFlightDirection.pop) {
              return FadeTransition(
                opacity: AlwaysStoppedAnimation(0),
                child: toHero.child,
              );
            } else {
              return toHero.child;
            }
          },
          child: FlatButton(
            child: Text("prev 1"),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
          tag: "test",
        ));
  }
}

在您的 SecondRoute(應該彈出的flightShuttleBuilder )中,您必須為您的Hero提供一個flightShuttleBuilder參數,然后您可以檢查方向,如果它正在彈出,只需使用AlwaysStoppedAnimation淡入淡出過渡隱藏小部件

結果是這樣的: 在此處輸入圖片說明

我希望這是像預期的結果,當然你可以完全改變flightShuttleBuilder里面的transition來改變效果! 由你決定 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM