Flutter-PositionedTransition位置变化

2019-07-24  本文已影响0人  秋分落叶

1)PositionedTransition是AnimatedWidget的子类,跟AnimatedBuilder一样。主要是为了在使用动画的过程中减少不必要的Widget对象的创建工作,提高效率。
2)该类持有了一个Animation<RelativeRect>的引用rect
3)在build构建widget的时候使用了动画rect.value,在这里这个value就是RelativeRect对象。

那么这个RelativeRect对象是什么呢?在回答这个问题之前先来看看官方文档给的例子,通过这个视频可以看出PositionedTranstion是用来干嘛的。

width="560" height="315" src=" https://flutter.github.io/assets-for-api-docs/assets/widgets/positioned_transition.mp4" allowfullscreen="">
显而易见,PositionedTranstion通过一个特定的动画Animation<RelativeRect>将Widget的位置从动画的生命周期的起始位置移到结束位置。而这个位置信息就是RelativeRect来表示,Relative相对的意思,相对谁?相对于某个Widget,而不是相对于坐标原点。RelativeRect有四个属性:

//widget的左边框距离此RelativeRect的左边框的距离
 final double left;
 //widget的上边框距离此RelativeRect的上边框的距离
  final double top;
   //widget的右边框距离此RelativeRect的右边框的距离
  final double right;
    //widget的底边框距离此RelativeRect的底部边框的距离
  final double bottom;

所以如果我们想让一个widget的位置(上下左右)距离RelativeRect都是100的话,就要这么写:

  RelativeRect.fromLTRB(
      100.0,///l child.left 到此left边的距离为0
      100.0,///t child.top的距离到此rect.top的距离为0
      100.0,///r child.right的距离到此rect.rignt的距离为0
      100.0,///t child.bottom到此rect.bottom边的距离为100
    )
  1. 创建自定义转场类
import 'package:flutter/material.dart';

class ScaleRoute extends PageRouteBuilder {
  final Widget widget;
  final RelativeRect rect;
  ScaleRoute({@required this.widget, @required this.rect}) :
      super(pageBuilder: (BuildContext context,Animation<double> animation, Animation<double> secondaryAnimation) { return widget; },
      transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
          return Stack(
            children: [
             Container(),
              PositionedTransition(
                child: child,
                rect: RelativeRectTween(
                  begin: rect,
                  end: RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0),
                ).animate(animation),
              ),
            ],
          );
        },
        transitionDuration: Duration(milliseconds: 300),
      );
}
  1. 使用方法
        var rect = RelativeRect.fromLTRB(
            horizontalOffset, topOffset, horizontalOffset, bottomOffset);
        Navigator.push(
          context,
          ScaleRoute(
            rect: rect,
            widget: DetailScreen(
              taskId: task.id,
              heroIds: heroIds,
            ),
          ),
          // MaterialPageRoute(
          //   builder: (context) => DetailScreen(
          //         taskId: task.id,
          //         heroIds: heroIds,
          //       ),
          // ),
        );

运行效果如下:

image.png

注意:

image.png
从上面代码可以看出PositionedTransition必须作为Stack这个widget的child Widget来使用
上一篇 下一篇

猜你喜欢

热点阅读