1

How to run animation in a widget which is a ScopedModeldescendant, from the scoped-model. I have a red button here which when clicked shows a square. The square is made to disappear after 3 seconds, which happens to quickly. What I want to do is make the square fade away in a few seconds. I tried AnimationController but it requires a 'vsync:' parameter which I've seen is usually done in an initState() as 'vsync: this' and gives an error when used elsewhere.

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'scoped model Opacity',
      home: new ScopedModel<MyScopedModel>(
        model: new MyScopedModel(),
        child: new MyPage(),
      ),
    );
  }
}

class MyScopedModel extends Model {
  double myOpacity = 0.0;
  Timer myTimer;

  AnimationController myAnimationController;

  void myShowSquare() {
    myOpacity = 1.0;
    myTimer = new Timer(new Duration(seconds: 3), _removeSquare);
    notifyListeners();
  }

  void _removeSquare() {
    myOpacity = 0.0;
    myTimer.cancel();
    notifyListeners();
  }
}

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
        color: Colors.grey,
        child: new ScopedModelDescendant<MyScopedModel>(
          builder: (context, child, model) => new Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  new GestureDetector(
                    onTap: model.myShowSquare,
                    child: new Stack(
                      alignment: Alignment.center,
                      children: <Widget>[
                        new Container(
                          constraints: new BoxConstraints.expand(
                              width: 50.0, height: 50.0),
                          color: Colors.deepOrange,
                        ),
                        new Text(
                          '+',
                          style: new TextStyle(color: Colors.black),
                        ),
                      ],
                    ),
                  ),
                  new Opacity(
                    opacity: model.myOpacity,
                    child: new Container(
                      constraints:
                          new BoxConstraints.expand(width: 50.0, 
                                height: 50.0),
                      color: Colors.amber,
                    ),
                  )
                ],
              ),
        ));
  }
}
Pablo Cegarra
  • 20,955
  • 12
  • 92
  • 110
Ant D
  • 2,481
  • 6
  • 18
  • 34

1 Answers1

2

I think what you're looking for is a FadeTransition which I believe handles the hard work for you of fading your widget out. You could also potentially use the AnimatedCrossFade widget if you want to change sizes as well.

However, if you're looking to animate things yourself I'd advise looking at the Animation documentation and this Animation Tutorial as they will explain the details of how it works.

rmtmckenzie
  • 37,718
  • 9
  • 112
  • 99
  • I can use FadeTransition and I also plan to do other types of animations. Well I think I'II have to read up on the Animation tutorials. Thanks. I was looking if it was possible to implement the TickerProvider abstract class. – Ant D Apr 24 '18 at 03:08
  • If you extend the SingleTickerProviderStateMixin it makes your widget class a ticker provider. I believe that whichever widget is the ticker provider should contain the entire animation for performance reasons – rmtmckenzie Apr 24 '18 at 04:18
  • I reached up to making the model class a TickerProvider with the 'implements TickerProvider' and I had to @override Ticker createTicker(TickerCallback onTick) { // TODO: implement createTicker } and this is where I am lost. The documentation is of no help. I think I'II go with your suggestion of extending the widget class with the TickerProviderStatemixin. – Ant D Apr 24 '18 at 07:33
  • The simple answer to that is to create a `new Ticker()` and return it, but using the SingleTickerProviderStateMixin should do what you need and handles things like saving & disposing of the Ticker at the proper times. The [SingleTickerProviderStateMixin source](https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/widgets/ticker_provider.dart) might help you understand what they're doing there. – rmtmckenzie Apr 24 '18 at 15:11