Как добавить анимацию класса Curves в AnimationController во Flutter? - PullRequest
1 голос
/ 26 марта 2019

Я пытаюсь добавить анимацию класса кривых Curves.bounceOut в мой код, который использует AnimationController.

Вот мой код:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  var squareScale = 1.0;
  static AnimationController _controller;

  @override
  void initState() {
    _controller = AnimationController(
        vsync: this,
        lowerBound: 0.5,
        upperBound: 1.0,
        duration: Duration(milliseconds: 300));

    _controller.addListener(() {
      setState(() {
        squareScale = _controller.value;
      });
    });

    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Bounce Example"),
      ),
      body: Stack(
        children: <Widget>[
          Container(
            width: 150.0,
            height: 150.0,
            color: Colors.yellowAccent,
          ),
          Column(
            children: <Widget>[
              Row(
                children: <Widget>[
                  GestureDetector(
                    onTap: () {
                      _controller.forward(from: 0.0);
                    },
                    child: Transform.scale(
                      scale: squareScale,
                      child: Container(
                        width: 150.0,
                        height: 150.0,
                        color: Colors.green,
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }
}

В настоящее время зеленый контейнер оживляет от 0,5 до 1,0, но не отскакивает. Как добавить анимацию «Curves.bounceOut», чтобы контейнер подпрыгивал при нажатии?

Заранее спасибо за любую помощь!

1 Ответ

2 голосов
/ 26 марта 2019

Вы захотите использовать как контроллер анимации, так и анимацию движения, что позволит вам добавить Curves.bounceOut.

Где-то в вашем коде добавьте:

AnimationController _controller;
var scaleAnimation;

А в вашем initState() методе:

_controller = new AnimationController(
 duration: new Duration(milliseconds: 300),
 vsync: this
)
..addListener(() {
  setState(() {});
});
scaleAnimation = new Tween(
  begin: 0.5,
  end: 1.0,
).animate(new CurvedAnimation(
  parent: _controller,
  curve: Curves.bounceOut
));

Обратите внимание, что ..addListener() - хороший код дротика, который позволяет легко добавлять слушателя. Tween в основном говорит вашей анимации, что она должна перейти от значения в begin к значению в end в течение периода времени, указанного в AnimationController. Чтобы использовать это значение в своем коде, вы можете просто установить масштаб результата анимации:

child: Transform.scale(
  scale: scaleAnimation.value,
  child: Container(
    width: 150.0,
    height: 150.0,
    color: Colors.green,
  ),
),

А когда вызывается анимация, она автоматически обновляет масштаб контейнера.

Edit:

Измените свой виджет на это:

child: isChanging ? Transform.scale(
  scale: scaleAnimation.value,
  child: Container(
    width: 150.0,
    height: 150.0,
    color: Colors.green,
  ),
) : Transform.scale(
  scale: 1.0,
  child: Container(
    width: 150.0,
    height: 150.0,
    color: Colors.green,
  ),
),

Сохраните ваши параметры begin и end как 0.5 и 1.0 соответственно, но в вашем методе onTap() перед отправкой контроллера добавьте:

onTap: () {
  setState(() {
    isChanging = true
  });
  _controller.forward(from: 0.0);
}

И в любом месте вашего кода добавьте строку bool isChanging. Наконец, вы захотите сбросить показанный виджет в конце вашей анимации, поэтому измените scaleAnimation на:

child: Transform.scale(
  scale: scaleAnimation.value,
  child: Container(
    width: 150.0,
    height: 150.0,
    color: Colors.green,
  ),
)..addStatusListener((AnimationStatus status) {
  if (status == AnimationStatus.completed) { //the animation is finished
    _controller.reset();
    setState(() {
      isChanging = false;
    }
  }
});
...