【问题标题】:How to pass animation value to a child widget如何将动画值传递给子小部件
【发布时间】:2023-03-10 09:11:01
【问题描述】:

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

我尝试直接传递动画,但随后应用崩溃并出现错误“The getter value was called on null”。

编辑:使用代码。我的问题是 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(),
        ),
      ],
    );
  }
}

【问题讨论】:

  • 你能显示一些代码吗?
  • @JordanDavies 我已经添加了代码,谢谢!

标签: flutter flutter-animation


【解决方案1】:

with SingleTickerProviderStateMixin 添加到子小部件使错误消失!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多