如何将动画值传递给子窗口小部件

时间:2019-01-21 10:04:08

标签: flutter flutter-animation

我有一个定义动画的小部件。该动画从0.0前进到1.0。这个小部件还有一个子小部件,我想控制其不透明度与动画进度同步。但是,我看不到如何使子窗口小部件的状态“跟踪”父窗口小部件动画进度的状态。我从父母给孩子的任何东西最终都是final,因此是一成不变的。

我尝试直接传递动画,但是应用程序崩溃,并显示错误“在空调用getter value”。

编辑:带有代码。我的问题是,无法使MenuItem类知道Animation值的状态。


import 'package:flutter/material.dart';

class MenuItem extends StatefulWidget {
  final Function() onPressed;
  final String tooltip;
  final String helper;
  final IconData icon;

  MenuItem({this.onPressed, this.tooltip, this.helper, this.icon});

  @override
  _MenuItemState createState() => _MenuItemState();
}

class _MenuItemState extends State<MenuItem> {
  bool isOpened = true;
  double _elevateButtonValue = 0.0;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          AnimatedOpacity(
            opacity: isOpened ? 1.0 : 0.0,
            duration: Duration(milliseconds: 500),
            child: new Container(
              child: Text(widget.helper),
                decoration: new BoxDecoration (
                  borderRadius: new BorderRadius.all(const Radius.circular(8.0)),
                  color: Colors.white,
                  boxShadow: [new BoxShadow(
                    color: Colors.black.withOpacity(0.3),
                    offset: Offset(0.0, 6.0),
                    blurRadius: 16.0,
                  ),
                ],
              ),
              padding: new EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0),
            ),
          ),
          SizedBox(width: 12.0),
          FloatingActionButton(
            onPressed: () {},
            tooltip: widget.tooltip,
            child: Icon(widget.icon),
            backgroundColor: Colors.deepOrange,
            elevation: _elevateButtonValue,
          ),
        ],
      ),
    );
  }
}

class MenuFabs extends StatefulWidget {
  @override
  _MenuFabsState createState() => _MenuFabsState();
}

class _MenuFabsState extends State<MenuFabs>
    with SingleTickerProviderStateMixin {
  bool isOpened = false;
  AnimationController _animationController;
  Animation<Color> _buttonColor;
  Animation<double> _animateIcon;
  Animation<double> _translateButton;
  Animation<double> _elevateButton;
  Curve _curve = Curves.easeOut;
  double _fabHeight = 56.0;

  @override
  initState() {
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500))
          ..addListener(() {
            setState(() {});
          });
    _animateIcon =
        Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
    _buttonColor = ColorTween(
      begin: Colors.deepOrange,
      end: Colors.black45,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.00,
        1.00,
        curve: Curves.linear,
      ),
    ));
    _translateButton = Tween<double>(
      begin: _fabHeight,
      end: -14.0,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.0,
        0.75,
        curve: _curve,
      ),
    ));
    _elevateButton = Tween<double>(
      begin: 0.0,
      end: 6.0,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.25,
        1.0,
        curve: _curve,
      ),
    ));
    super.initState();
  }

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

  animate() {
    if (!isOpened) {
      _animationController.forward();
    } else {
      _animationController.reverse();
    }
    isOpened = !isOpened;
  }

  Widget goal() {
    return Container(
      child: new MenuItem(
        onPressed: () {},
        tooltip: 'Geolocate',
        helper: 'Geolocate',
        icon: Icons.radio_button_checked,
      ),
    );
  }

  Widget invite() {
    return Container(
      child: new MenuItem(
        onPressed: () {},
        tooltip: 'Invite friends',
        helper: 'Invite friends',
        icon: Icons.person_add,
      ),
    );
  }

  Widget toggle() {
    return Container(
      child: FloatingActionButton(
        backgroundColor: _buttonColor.value,
        onPressed: animate,
        tooltip: 'Toggle',
        child: AnimatedIcon(
          icon: AnimatedIcons.menu_close,
          progress: _animateIcon,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: <Widget>[
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value * 2.0,
            0.0,
          ),
          child: goal(),
        ),
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value,
            0.0,
          ),
          child: invite(),
        ),
        Transform(
          transform: Matrix4.translationValues(
            168.0,
            0.0,
            0.0,
          ),
          child: toggle(),
        ),
      ],
    );
  }
}

1 个答案:

答案 0 :(得分:0)

向子窗口小部件添加attribute_pa_style => circle可以使错误消失!