Getx: AnimationController inside Get App

Created on 23 Oct 2020  路  6Comments  路  Source: jonataslaw/getx

I am working on an App and wanted to give the UI some nice animations. But im struggling on implementing an AnimationController in a StatelessWidget. Anyone knows how to do that?

Most helpful comment

I'm putting here a code example as a reference for other issues about animation and SingleGetTickerProviderMixin:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(GetMaterialApp(
    initialRoute: '/home',
    getPages: [
      GetPage(
        name: '/home',
        page: () => HomePage(),
      ),
      GetPage(
          name: '/login',
          page: () => LoginPage(),
          binding: LoginBinding(),
          transition: Transition.fade),
    ],
  ));
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('HOME')),
      body: Center(
        child: RaisedButton(
          onPressed: () => Get.toNamed('/login'),
          child: Text('Login'),
        ),
      ),
    );
  }
}

class LoginBinding extends Bindings {
  @override
  void dependencies() {
    Get.put(LoginController());
  }
}

class LoginController extends GetxController with SingleGetTickerProviderMixin {
  AnimationController _animationController;
  Animation<double> animationLogo;
  Animation<double> animationTextFieldUser;
  final duration = const Duration(milliseconds: 1000);

  @override
  void onInit() {
    _animationController = AnimationController(duration: duration, vsync: this);

    animationLogo = Tween<double>(begin: 0, end: 150).animate(_animationController)
      ..addListener(() => update());
    animationTextFieldUser = Tween<double>(begin: Get.width, end: 0).animate(_animationController)
      ..addListener(() => update());

    _animationController.forward();
    super.onInit();
  }

  @override
  void onClose() {
    _animationController.dispose();
    super.onClose();
  }
}

class LoginPage extends GetView<LoginController> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Container(
        padding: EdgeInsets.all(10),
        child: GetBuilder<LoginController>(
          builder: (_) {
            return Column(
              children: [
                SizedBox(
                  height: 200,
                  child: Container(
                    height: _.animationLogo.value,
                    width: _.animationLogo.value,
                    child: FlutterLogo(),
                  ),
                ),
                AnimatedBuilder(
                  child: TextField(
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'User',
                    ),
                  ),
                  animation: _.animationTextFieldUser,
                  builder: (context, child) {
                    return Transform.translate(
                      offset: Offset(_.animationTextFieldUser.value, 0),
                      child: child,
                    );
                  },
                )
              ],
            );
          },
        ),
      ),
    );
  }
}

All 6 comments

I am working on an App and wanted to give the UI some nice animations. But im struggling on implementing an AnimationController in a StatelessWidget. Anyone knows how to do that?

https://github.com/jonataslaw/getx/issues/117#issuecomment-674357259

Thank you!

You can too use SingleGetTickerProviderMixin.
As this was answered, I'm closing

I'm putting here a code example as a reference for other issues about animation and SingleGetTickerProviderMixin:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(GetMaterialApp(
    initialRoute: '/home',
    getPages: [
      GetPage(
        name: '/home',
        page: () => HomePage(),
      ),
      GetPage(
          name: '/login',
          page: () => LoginPage(),
          binding: LoginBinding(),
          transition: Transition.fade),
    ],
  ));
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('HOME')),
      body: Center(
        child: RaisedButton(
          onPressed: () => Get.toNamed('/login'),
          child: Text('Login'),
        ),
      ),
    );
  }
}

class LoginBinding extends Bindings {
  @override
  void dependencies() {
    Get.put(LoginController());
  }
}

class LoginController extends GetxController with SingleGetTickerProviderMixin {
  AnimationController _animationController;
  Animation<double> animationLogo;
  Animation<double> animationTextFieldUser;
  final duration = const Duration(milliseconds: 1000);

  @override
  void onInit() {
    _animationController = AnimationController(duration: duration, vsync: this);

    animationLogo = Tween<double>(begin: 0, end: 150).animate(_animationController)
      ..addListener(() => update());
    animationTextFieldUser = Tween<double>(begin: Get.width, end: 0).animate(_animationController)
      ..addListener(() => update());

    _animationController.forward();
    super.onInit();
  }

  @override
  void onClose() {
    _animationController.dispose();
    super.onClose();
  }
}

class LoginPage extends GetView<LoginController> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Container(
        padding: EdgeInsets.all(10),
        child: GetBuilder<LoginController>(
          builder: (_) {
            return Column(
              children: [
                SizedBox(
                  height: 200,
                  child: Container(
                    height: _.animationLogo.value,
                    width: _.animationLogo.value,
                    child: FlutterLogo(),
                  ),
                ),
                AnimatedBuilder(
                  child: TextField(
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'User',
                    ),
                  ),
                  animation: _.animationTextFieldUser,
                  builder: (context, child) {
                    return Transform.translate(
                      offset: Offset(_.animationTextFieldUser.value, 0),
                      child: child,
                    );
                  },
                )
              ],
            );
          },
        ),
      ),
    );
  }
}

Captura de Pantalla 2020-11-15 a la(s) 11 46 24
im using a tween in my case and this happens

Code

class HomeController extends GetxController with SingleGetTickerProviderMixin {
  AnimationController _ac;
  Animation<double> _elevationTween;

  @override
  void onInit() {
    _ac = AnimationController.unbounded(
      duration: Duration(seconds: 1),
      vsync: this,
    );

    _elevationTween = Tween(begin: 1.0, end: 20.0).animate(_ac);
    _ac.repeat(reverse: true);

    super.onInit();
  }

  @override
  void onClose() {
    _ac.dispose();
    super.onClose();
  }

  double get elevation => _elevationTween.value ?? 0.0;
}

Removing the unbounded constructor makes it work. But animation doesnt happen

@jpkontreras, this issue is closed. Please open a new issue and provide a valid source code (main, view, controller) that demonstrates the problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ChiwanAhn picture ChiwanAhn  路  4Comments

definev picture definev  路  3Comments

wailashraf71 picture wailashraf71  路  4Comments

aytunch picture aytunch  路  4Comments

manojeeva picture manojeeva  路  3Comments