在 Flutter 中滚动时如何为 SingleChildScrollView 使用平滑动画?

时间:2021-01-05 12:18:28

标签: flutter animation flutter-layout flutter-web flutter-animation

这是我的代码片段。我尝试使用 8 个图像在 flutter web 中开发视差动画效果 开发我的作品集网站。我从 firewatch 网站启​​发了这一点。我想使用 Flutter 来实现这种效果。

首先看看这个image

这是代码片段。

import 'package:flutter/material.dart';
void main() {
  runApp(MyPortfolio());
}

class MyPortfolio extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'We Can Code',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  double offset = 0;
  double rateZero = 0;
  double rateOne = 0;
  double rateTwo = 0;
  double rateThree = 0;
  double rateFour = 0;
  double rateFive = 0;
  double rateSix = 0;
  double rateSeven = 0;
  double rateEight = 90;

  String asset;
  double top;

  @override
  Widget build(BuildContext context) {
    final height = MediaQuery.of(context).size.height;
    final width = MediaQuery.of(context).size.width;
    final nameStyle = Theme.of(context).textTheme.headline2;
    final descriptionStyle = Theme.of(context).textTheme.headline4;
    return Material(
      child: NotificationListener<ScrollNotification>(
        // When user scrolls, this will trigger onNotification.
        // updateOffsetAccordingToScroll updates the offset
        onNotification: (v) {
          if (v is ScrollUpdateNotification) {
        //only if scroll update notification is triggered
        setState(() {
          rateEight -= v.scrollDelta / 1;
          rateSeven -= v.scrollDelta / 1.5;
          rateSix -= v.scrollDelta / 2;
          rateFive -= v.scrollDelta / 2.5;
          rateFour -= v.scrollDelta / 3;
          rateThree -= v.scrollDelta / 3.5;
          rateTwo -= v.scrollDelta / 4;
          rateOne -= v.scrollDelta / 4.5;
          rateZero -= v.scrollDelta / 5;
        });
          }
          return false;
        },
        // ScrollConfiguration sets the scroll glow behaviour
        child: ScrollConfiguration(
          behavior: NoScrollGlow(),
          child: Stack(
            children: <Widget>[
              ParallaxWidget(
                top: rateZero,
                asset: "parallax0",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateOne,
                asset: "parallax1",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateTwo,
                asset: "parallax2",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateThree,
                asset: "parallax3",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateFour,
                asset: "parallax4",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateFive,
                asset: "parallax5",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateSix,
                asset: "parallax6",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateSeven,
                asset: "parallax7",
                height: height,
                width: width,
              ),
              ParallaxWidget(
                top: rateEight,
                asset: "parallax8",
                height: height,
                width: width,
              ),

              SingleChildScrollView(
                child: Column(
                  children: <Widget>[
                    SizedBox(height: height),
                    Container(
                      height: 50,
                      width: width,
                      color: Color(0xff210002),

                    ),
                    Container(
                      height: height-50,
                      width: width,
                      color: Color(0xffFFAF1B),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

}

class NoScrollGlow extends ScrollBehavior {
  @override
  Widget buildViewportChrome(
      BuildContext context,
      Widget child,
      AxisDirection axisDirection,
      ) {
    return child;
  }
}

class ParallaxWidget extends StatelessWidget {
  const ParallaxWidget({
    Key key,
    @required this.top,
    @required this.asset,
    @required this.height,
    @required this.width,
  }) : super(key: key);

  final double top;
  final String asset;
  final double height;
  final double width;

  @override
  Widget build(BuildContext context) {
    return AnimatedPositioned(
      duration: Duration(milliseconds: 1000),
      left: -45,
      top: top,
      child: Container(
        height: height,
        width: width + 50 ,
        child: Image.asset("$asset.png", fit: BoxFit.cover),
      ),
    );
  }
}

我使用 AnimatedPosition 来平滑滚动小部件。但是 SingleChildScrollView 滚动不顺畅。而且它在视差中也不能完美地与最后一张图像一起移动。(所以你可以看到动画中有缺陷并且看起来很凌乱)。如果我替换 SingleChildScrollView 就实现了。但它们有一种断断续续的效果(不平滑)。我尝试了一种动画 SingleChildScrollView 的方法。但没有任何效果。有没有其他方法可以实现这一点。请帮帮我。提前致谢。

0 个答案:

没有答案