Flutter samples animations 03_animation_controllerをflutter_hooksで書き換える

書き換える前

https://github.com/flutter/samples/blob/master/animations/lib/src/basics/03_animation_controller.dart

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

void main() => runApp(MaterialApp(
      home: AnimationControllerDemo(),
    ));

class AnimationControllerDemo extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final controller = useAnimationController(duration: Duration(seconds: 1));
    // https://github.com/rrousselGit/flutter_hooks/issues/204
    // を見て気づいた
    useListenable(controller);

    return Scaffold(
      appBar: AppBar(
        title: Text('Animation Controller'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ConstrainedBox(
              constraints: BoxConstraints(maxWidth: 200),
              child: Text(
                '${controller.value.toStringAsFixed(2)}',
                style: Theme.of(context).textTheme.headline3,
                textScaleFactor: 1 + controller.value,
              ),
            ),
            ElevatedButton(
              child: Text('animate'),
              onPressed: () {
                if (controller.status == AnimationStatus.completed) {
                  controller.reverse();
                } else {
                  controller.forward();
                }
              },
            )
          ],
        ),
      ),
    );
  }
}

もともとのソースの下記の部分の書き換えがわからずに苦労しました。 特にAnimationController.valueが変更されるたびにsetStateみたいなものを実行するのがわかりませんでした。

controller = AnimationController(vsync: this, duration: _duration)
      ..addListener(() {
        setState(() {});
      });

ですが、冷静にflutter_hooksのissueを見ていたらuseListenableを使えばいいことに気づきました。

ただ、変更が起きるところをAnimatedBuilderを囲えばuseListenableは不要です。