Repository: flutter
Issue: improving AnimationController.unbounded
Labels: framework,a: animation,d: api docs,P3,team-framework,triaged-framework

it's not clear how to use unbounded animation controller, it should be better documented with an example

https://github.com/flutter/flutter/blob/696e4f70d1a7a9b9b793aa3fc4ad2d8d3d8eac17/packages/flutter/lib/src/animation/animation_controller.dart#L251-L282

moreover, it seems like behavior with other methods than `animateWith` (which drives a simulation) is simply not defined.
also, it doesn't have any tests except for default parameters

<details>
<summary>reproducible</summary>

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'App',
      home: Home(),
    );
  }
}

enum Test {
  reset,
  forward,
  animateTo,
  reverse,
  fling,
}

class Home extends StatefulWidget {
  Home({Key key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
  AnimationController controller;
  @override
  void initState() {
    super.initState();
    controller = AnimationController.unbounded(vsync: this, duration: const Duration(milliseconds: 2000));
    controller.addListener(_listener);
    controller.addStatusListener(_statusListener);

    switch(Test.reset) {
      case Test.reset:
        // here it should either have initial value of 0.0 and reset() to 0.0, either in both cases -Infinity
        print(controller.value); // outputs 0.0
        controller.forward();
        controller.reset();
        print(controller.value); // outputs -Infinity
      break;
      case Test.forward:
        /// jumps to inifinity instantaneously, reports [AnimationStatus.completed] after 2000 milliseconds
        //
        // outputs:
        //    AnimationStatus.forward
        //    0.0
        //    0.0
        //    Infinity
        //    Infinity
        //    Infinity
        //    .......
        //    AnimationStatus.completed
        controller.forward();
      break;
      case Test.animateTo:
        // works as expected
        //
        // outputs:
        //    AnimationStatus.forward
        //    0.00416275
        //    0.00833175
        //    0.01249775
        //    0.01666425
        //    0.02083325
        //    .......
        //    AnimationStatus.completed
        controller.animateTo(0.5);
      break;
      case Test.reverse:
        /// jumps to -inifinity instantaneously, reports [AnimationStatus.dismissed] after 2000 milliseconds
        //
        // outputs:
        //    AnimationStatus.reverse
        //    0.0
        //    0.0
        //    -Infinity
        //    -Infinity
        //    -Infinity
        //    .......
        //    AnimationStatus.dismissed
        controller.reverse();
      break;
      case Test.fling:
        /// jumps to -inifinity instantaneously (but without two 0.0 like for forward() and reverse()),
        /// but never reports [AnimationStatus.completed] or [AnimationStatus.dismissed]
        //
        // outputs:
        //    AnimationStatus.forward
        //    Infinity
        //    Infinity
        //    Infinity
        //    Infinity
        //    ........
        controller.fling();
      break;
      default:
        assert(false);
    }
  }

  void _listener() {
    print(controller.value);
  }

  void _statusListener(AnimationStatus status) {
    print(status);
  }

  @override
  void dispose() { 
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
```
</details>

/cc @Hixie