Flutter Animation - перемещаться вверх при отображении с помощью Matrix4 - PullRequest
1 голос
/ 12 марта 2020

Есть ли встроенная анимация во флаттере, которая действует как на странице ниже? Пример: длинная страница с прокруткой и, когда мы прокручиваем вниз, новое содержимое появляется на экране и слегка перемещается вверх.

piedpiper

1 Ответ

3 голосов
/ 22 марта 2020

AnimatedList может помочь в этом, я думаю, также вы можете использовать его с StreamBuilder тоже, если вам нужно. https://api.flutter.dev/flutter/widgets/AnimatedList-class.html

Или вы можете использовать AnimatedContainer для каждой страницы ниже; https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html

Редактировать: Пример кода;

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ListView(
          children: [Container(
            color: Colors.blue,
            height: 1000,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                SlideFadeTransition(
                    delayStart: Duration(milliseconds: 800),
                    offset: 2,
                    child: new Text('Test Text 1')),
                SlideFadeTransition(
                    delayStart: Duration(milliseconds: 1200),
                    offset: 4,
                    child: new Text('Test Text 2'))
              ],
            ),
          ),
            Container(
              color: Colors.red,
              height: 1000,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  SlideFadeTransition(
                      delayStart: Duration(milliseconds: 1200),
                      offset: 2,
                      child: new Text('Test Text 1')),
                  SlideFadeTransition(
                      delayStart: Duration(milliseconds: 2400),
                      offset: 4,
                      child: new Text('Test Text 2'))
                ],
              ),
            ),
            Container(
              color: Colors.orange,
              height: 1000,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  SlideFadeTransition(
                      delayStart: Duration(milliseconds: 1200),
                      offset: 2,
                      child: new Text('Test Text 1')),
                  SlideFadeTransition(
                      delayStart: Duration(milliseconds: 2400),
                      offset: 4,
                      child: new Text('Test Text 2'))
                ],
              ),
            ),
  ]
    )
    )
    );
  }
}


enum Direction { vertical, horizontal }

class SlideFadeTransition extends StatefulWidget {
  ///The child on which to apply the given [SlideFadeTransition]
  final Widget child;

  ///The offset by which to slide and [child] into view from [Direction].
  ///Defaults to 0.2
  final double offset;

  ///The curve used to animate the [child] into view.
  ///Defaults to [Curves.easeIn]
  final Curve curve;

  ///The direction from which to animate the [child] into view. [Direction.horizontal]
  ///will make the child slide on x-axis by [offset] and [Direction.vertical] on y-axis.
  ///Defaults to [Direction.vertical]
  final Direction direction;

  ///The delay with which to animate the [child]. Takes in a [Duration] and
  /// defaults to 0.0 seconds
  final Duration delayStart;

  ///The total duration in which the animation completes. Defaults to 800 milliseconds
  final Duration animationDuration;

  SlideFadeTransition({
    @required this.child,
    this.offset = 0.2,
    this.curve = Curves.easeIn,
    this.direction = Direction.vertical,
    this.delayStart = const Duration(seconds: 0),
    this.animationDuration = const Duration(milliseconds: 800),
  });
  @override
  _SlideFadeTransitionState createState() => _SlideFadeTransitionState();
}

class _SlideFadeTransitionState extends State<SlideFadeTransition>
    with SingleTickerProviderStateMixin {
  Animation<Offset> _animationSlide;

  AnimationController _animationController;

  Animation<double> _animationFade;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: widget.animationDuration,
    );

    //configure the animation controller as per the direction
    if (widget.direction == Direction.vertical) {
      _animationSlide =
          Tween<Offset>(begin: Offset(0, widget.offset), end: Offset(0, 0))
              .animate(CurvedAnimation(
            curve: widget.curve,
            parent: _animationController,
          ));
    } else {
      _animationSlide =
          Tween<Offset>(begin: Offset(widget.offset, 0), end: Offset(0, 0))
              .animate(CurvedAnimation(
            curve: widget.curve,
            parent: _animationController,
          ));
    }

    _animationFade =
        Tween<double>(begin: -1.0, end: 1.0).animate(CurvedAnimation(
          curve: widget.curve,
          parent: _animationController,
        ));

    Timer(widget.delayStart, () {
      _animationController.forward();
    });
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
      opacity: _animationFade,
      child: SlideTransition(
        position: _animationSlide,
        child: widget.child,
      ),
    );}}
...