可以使用Flutter复制iOS App Store过渡吗? [英] Possible to copy iOS App Store transition using Flutter?

查看:128
本文介绍了可以使用Flutter复制iOS App Store过渡吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用Flutter复制iOS App Store的过渡效果?

Is it possible to copy the transition effect of iOS App Store using Flutter?

我尝试通过将两个标签放置在两个小部件的根布局中来使用Hero Animation,但是动画看起来很怪异,不是我期望的那样.但是,这样做的好处是,当我使用MaterialPageRoute时,我能够向后滑动iOS.

I tried using Hero Animation by placing two tags into the root layout of both widgets, but animation looks janky or not what I expected. But good thing about this is I am able to do iOS swipe back as I'm using MaterialPageRoute.

来源

Hero(
   tag: 'heroTag_destinationScreen',
   transitionOnUserGestures: true,
   flightShuttleBuilder: (BuildContext flightContext,
     Animation<double> animation,
     HeroFlightDirection flightDirection,
     BuildContext fromHeroContext,
     BuildContext toHeroContext,) {
        final Hero toHero = toHeroContext.widget;
            return ScaleTransition(
              scale: animation,
              child: toHero,
            );
          },
          child: GestureDetector(
            onTap: () {
              Navigator.of(context).push(
                MaterialPageRoute<void>(
                  builder: (BuildContext context) {
                    return DestinationScreen()
                  },
                ),
              );
            },
            child: Card(
                ...someCardContent
            ),
      ),
)

目标屏幕

@override
Widget build(BuildContext context) {
    return Hero(
       tag: 'heroTag_destinationScreen',
       child: Scaffold(
           appBar: ...someAppBar
            body: ...someMainBodyContent
          ),
      )
    }

然后我一直在四处张望,Flutter团队创建了一个程序包,可以使用容器变换来模拟这种效果.我实现了它,效果很棒,但后来我无法从左向左滑动iOS设备,无法将布局缩小到卡片视图.

Then I have been looking around and there is a package created by Flutter team which can simulate this effect using container transform. I implemented it, works awesome but then I'm not able to do iOS swipe from left to go back and shrink the layout to card view.

https://pub.dev/packages/animations

推荐答案

这是我的解决方案.

https://imgur.com/2WYn6TX

(对不起,我无法发布图片.)

(Sorry for my reputation, I can't post a image.)

我自定义了英雄过渡,以尽可能地重塑App Store的过渡.

I customize hero transition to remake App store transition as much as possible.

      child: Hero(
        tag: widget.product.id,
        child: Image.asset(widget.product.image, fit: BoxFit.cover),
        flightShuttleBuilder:
            (flightContext, animation, direction, fromcontext, toContext) {
          final Hero toHero = toContext.widget;
          // Change push and pop animation.
          return direction == HeroFlightDirection.push
              ? ScaleTransition(
                  scale: animation.drive(
                    Tween<double>(
                      begin: 0.75,
                      end: 1.02,
                    ).chain(
                      CurveTween(
                          curve: Interval(0.4, 1.0, curve: Curves.easeInOut)),
                    ),
                  ),
                  child: toHero.child,
                )
              : SizeTransition(
                  sizeFactor: animation,
                  child: toHero.child,
                );
        },
      ),

接下来,我使用ScaleTransitiononVerticalDragUpdate来控制弹出动画.

Next, I use ScaleTransition and onVerticalDragUpdate to control pop animation.

https://imgur.com/a/xEMYOPr

double _initPoint = 0;
double _pointerDistance = 0;
GestureDetector(
  onVerticalDragDown: (detail) {
    _initPoint = detail.globalPosition.dy;
  },
  onVerticalDragUpdate: (detail) {
    _pointerDistance = detail.globalPosition.dy - _initPoint;
    if (_pointerDistance >= 0 && _pointerDistance < 200) {
        // scroll up
        double _scaleValue = double.parse((_pointerDistance / 100).toStringAsFixed(2));
        if (_pointerDistance < 100) {
          _closeController.animateTo(_scaleValue,
          duration: Duration(milliseconds: 300),
          curve: Curves.linear);
        }
    } else if (_pointerDistance >= 260) {
      if (_pop) {
        _pop = false;
        _closeController.fling(velocity: 1).then((_) {
          setState(() {
          _heightController.reverse();
          });
          Timer(Duration(milliseconds: 100), () {
            Navigator.of(context).pop();
          });
        });
      }
    } else {
      // scroll down
    }
  },
  onVerticalDragEnd: (detail) {
    if (_pointerDistance >= 550) {
      if (_pop) {
        _closeController.fling(velocity: 1).then((_) {
          setState(() {
            _heightController.reverse();
          });
          Timer(Duration(milliseconds: 100), () {
            Navigator.of(context).pop();
          });
        });
      }
    } else {
    _closeController.fling(velocity: -1);
    }
  },
  child: Hero(
    tag: _product.id,
    child: Image.asset(
      _product.image,
      fit: BoxFit.cover,
      height: 300,
    ),
  ),
),

如果将Hero用作动画,则需要自定义文本部分的过渡.

If use Hero as a animation, you need to customize the text section transition.

此处: https://imgur.com/a/gyD6tiZ

就我而言,我通过Sizetransition控制文本部分的过渡.

In my case, I control text section transition by Sizetransition.

// horizontal way and vertical way.
SizeTransition(
  axis: Axis.horizontal,
  sizeFactor: Tween<double>(begin: 0.5, end: 1).animate(
    CurvedAnimation(
        curve: Curves.easeInOut, parent: _widthController),
  ),
  child: SizeTransition(
    sizeFactor: Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(
          curve: Curves.easeInOut, parent: _heightController),
    ),
    child: Container(
      padding: EdgeInsets.only(
          left: 20, right: 20, top: 50, bottom: 30),
      width: double.infinity,
      color: Colors.white,
      constraints: BoxConstraints(
        minHeight: 650,
      ),
      child: Column(
        // title and text
        children: <Widget>[
          Text('Title', style: TextStyle(fontSize: 18)),
          SizedBox(height: 30),
          Text(_text,
              style: TextStyle(
                fontSize: 15,
              )),
        ],
      ),
    ),
  ),
),

尽管它与App Store不同,但我希望它对您有所帮助.

Although it isn't the same as App Store, i hope it is helpful for you.

源代码: https://github.com/HelloJunWei/app_store_transition

如果有任何建议,请随时反馈或创建请求请求. :)

If you have any suggestion, feel free to feedback or create a pull request. :)

这篇关于可以使用Flutter复制iOS App Store过渡吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆