从其他小部件控制动画

时间:2019-01-30 13:08:45

标签: flutter

我正在尝试使用从其他小部件(图片中的widget 2捕获的手势来控制小部件(图片中的widget 1)上的动画,但是我找不到正确的方法为此。

我目前正在考虑的方法是将AnimationController放在一个公共父级中。 widget 1将通过回调更新该控制器在父级中的值。 widget 2会收到该控制器一个参数,因此widget 2中的动画将对应于widget 1中的手势所提供的值

enter image description here

这是正确的方法吗?如果没有,哪种方法更好? 编辑:尝试此方法后,我注意到抛出了异常

Another exception was thrown: AnimationController.dispose() called more than once.

我怀疑AnimationController对象将在重建时重建,从而导致错误。关于如何避免这种情况的任何想法?

谢谢! :)

1 个答案:

答案 0 :(得分:1)

这里是我想使用AnimatedWidget试图达到的目标的完整示例。可能不是最有效的方法,但是它可以工作。

import 'package:flutter/material.dart';

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Test")),
        body: SafeArea(child: Parent()),
      ),
    );
  }
}

class Parent extends StatefulWidget {
  @override
  _ParentState createState() => _ParentState();
}

class _ParentState extends State<Parent> with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(vsync: this);
    _animation =
        Tween<double>(begin: 0, end: 100).animate(_animationController);
  }

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Expanded(child: Widget1(animation: _animation)),
        Widget2(onSliderChanged: (value) {
          _animationController.value = value / 100;
        }),
      ],
    );
  }
}

class Widget1 extends AnimatedWidget {
  Widget1({Key key, @required Animation<double> animation})
      : super(key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    Animation<double> animation = listenable;
    return Opacity(
      opacity: animation.value / 100,
      child: Center(
        child: Text(
          "Hi",
          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 40.0),
        ),
      ),
    );
  }
}

class Widget2 extends StatefulWidget {
  final ValueChanged<double> onSliderChanged;

  const Widget2({Key key, this.onSliderChanged}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _Widget2State();
}

class _Widget2State extends State<Widget2> {
  double _value = 0;

  @override
  Widget build(BuildContext context) {
    return Slider(
      value: _value,
      min: 0,
      max: 100,
      onChanged: (value) {
        setState(() {
          _value = value;
        });

        widget.onSliderChanged(value);
      },
    );
  }
}