【问题标题】:Animating widgets positions while scrolling滚动时为小部件位置设置动画
【发布时间】:2018-12-02 13:18:37
【问题描述】:

我正在尝试根据用户的滚动和滚动小部件 (CustomScrollView) 中的位置为我的应用中的小部件设置动画。

到目前为止,我使用我将在下面展示的方法实现了一些看起来非常不错的东西,但我担心这个特定的方法:

  1. 在性能和资源方面并不是最有效的。
  2. 不是最流畅的,会导致动画不流畅。
  3. 不会在所有类型的设备和分辨率上保持一致。

这是我想要实现的,注意文本的位置,以及左下角的滚动页面指示器:

我通过以下步骤实现了它:

  1. 创建一个函数 (_offsetPosition),它获取当前偏移量、小部件所属页面的索引、设备的视口尺寸以及我用来加速或减慢动画的系数.该函数将返回一个介于 -1.0 和 1.0 之间的值,而 -1.0 是在页面显示之前直到它显示在屏幕上的那一刻,1.0 只是它消失的时候,而 0.0 正是页面填满我的视口的时候。

  2. ScrollController 的侦听器中使用该函数,并根据我定义的滚动和其他常量更改变量的值,使其根据我的需要进行更改。

  3. 将该变量用作我的小部件的Padding(或任何其他参数,例如Opacity)。

这里是_offsetPosition 函数:

double _offsetPosition(double currentOffset, int pageIndex,
    double viewportDimension, double coefficient) {
  // Returns a value between -1.0 (left edge and before) to 1.0 (right edge and after).
  // 1.0 when the page fills the viewport exactly.
  // Making sure the return value won't be below -1.0 or 1.0 to avoid errors.
  double position = (currentOffset - pageIndex * viewportDimension) *
      coefficient /
      viewportDimension;

  if (position <= -1.0) {
    return -1.0;
  } else if (position >= 1.0) {
    return 1.0;
  } else {
    return position;
  }
}

这是我在initState 中定义的监听器,用于更改变量值,build 更改屏幕时:

void initState() {
  super.initState();

  _scrollController.addListener(() {
    setState(() {
      _pagePosition = _scrollController.offset /
          _scrollController.position.viewportDimension;

      _bg1Parallax = 0.2 -
          _offsetPosition(_scrollController.offset, 0,
                  _scrollController.position.viewportDimension, 1.0) *
              0.4;

      _bg2Parallax = 0.2 -
          _offsetPosition(_scrollController.offset, 1,
                  _scrollController.position.viewportDimension, 1.0) *
              0.4;

      _text1Padding = _offsetPosition(_scrollController.offset, 0,
              _scrollController.position.viewportDimension, 1.0) *
          1000.0;

      _text1Opacity = max(
          0.0,
          1.0 -
              _offsetPosition(_scrollController.offset, 0,
                      _scrollController.position.viewportDimension, 3.0)
                  .abs());
    });
  });
}

以下是用户滚动时移动的文本和图标小部件的示例,因为当用户向前滚动时_pagePosition_text1Padding 的值会增长,反之亦然:

图标小部件:

new Padding(
  padding:
      new EdgeInsets.only(left: _pagePosition * 20.0),
  child: new Padding(
    padding: new EdgeInsets.all(0.0),
    child: new Icon(
      FontAwesomeIcons.circle,
      size: 15.0,
      color: Colors.white,
    ),
  ),
)

文本小部件:

new Padding(
  padding: new EdgeInsets.only(bottom: _text1Padding),
  child: new Center(
    child: new Opacity(
      opacity: _text1Opacity,
      child: new Text(
        'Text',
        style: new TextStyle(
            fontSize: 100.0, color: Colors.white),
      ),
    ),
  ),
)

TL;DR

我是否应该使用根据ScrollController 偏移量更改的值作为Padding 参数来为小部件的位置设置动画?

【问题讨论】:

    标签: android animation dart flutter


    【解决方案1】:

    您是否尝试在真实设备上以发布模式运行您的应用?

    一般来说,当滚动位置发生变化时重建小部件树应该不是问题,因为 Flutter 是为了有效地处理这个问题而构建的(底层重 RenderObject 树没有重建)。

    另一种方法是使用自定义RenderSlivers、as demonstrated in the flutter_gallery example application。您可以在 Google Play 上下载应用程序(在应用程序中,选择研究 > 动画)。

    我录制了动画视频: https://i.imgur.com/Pj9x09q.mp4

    【讨论】:

      猜你喜欢
      • 2023-01-12
      • 2013-10-21
      • 2014-10-12
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多