加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

dart – Flutter Nested Widget Callback / Async Questions

发布时间:2020-12-14 14:52:43 所属栏目:百科 来源:网络整理
导读:从 Yueh Chou发布的 Flutter issue: Not sure if the event will bubble up to the parent widget and trigger the animation with all the nested widgets and callbacks. In the Original files, Pressing on a grandchild widget(e.g. FlatButton) of a
从 Yueh Chou发布的 Flutter issue:

Not sure if the event will bubble up to the parent widget and trigger
the animation with all the nested widgets and callbacks.

In the Original files,

Pressing on a grandchild widget(e.g. FlatButton) of a BackWidget it
will trigger a ModalDialog call and pressing the button will make an
async call. The Flip Effect will take place at the end of a successful
async call.

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


void main() {
  runApp(new MaterialApp(
      home: new Container(color: Colors.white,child: new RootWidget())));
}

class RootWidget extends StatelessWidget {
  FlipWidget mainFlipWidget;

  @override
  Widget build(BuildContext context) {
    mainFlipWidget = new FlipWidget(
      frontWidget: frontWidget,backWidget: new BackWidget(
        onPressedButton: () {
          _flipMainButton();
        },),);
    return new Center(child:mainFlipWidget);
  }

  _flipMainButton() {
    mainFlipWidget.doTheFlip();
  }
}

class BackWidget extends StatefulWidget {
  BackWidget({
    this.onPressedButton,});

  final VoidCallback onPressedButton;
   Widget buttonFlipWidget;
  _BackWidgetState createState() => new _BackWidgetState();
}

class _BackWidgetState extends State<BackWidget> {

  @override
  Widget build(BuildContext context) {
    widget.buttonFlipWidget = new Container(
      height: 180.0,color: Colors.grey[200],child:new FlatButton(
        onPressed: () {
          triggerCb();
        },child: new Text('Press me'),);
    return widget.buttonFlipWidget;
  }

  triggerCb() {
      widget.onPressedButton();
  }
}

class FlipWidget extends StatefulWidget {
  FlipWidget({
    @required this.frontWidget,@required this.backWidget,});

  final Widget frontWidget;
  final Widget backWidget;
  final _FlipWidgetState _state = new _FlipWidgetState();

  doTheFlip () {
    _state.doTheFlip();
  }

  _FlipWidgetState createState() => _state;
}

class _FlipWidgetState extends State<FlipWidget> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _frontScale;
  Animation<double> _backScale;

  void initState() {
    super.initState();
    _controller = new AnimationController(vsync: this,duration: const Duration(milliseconds: 1500),);
    _frontScale = new Tween(
      begin: 1.0,end: 0.0,).animate(new CurvedAnimation(parent: _controller,curve: new Interval(0.0,0.5,curve: Curves.easeIn),));
    _backScale = new CurvedAnimation(
      parent: _controller,curve: new Interval(0.5,1.0,curve: Curves.eaSEOut),);
  }

  @override
  Widget build(BuildContext context) {
//    ThemeData theme = Theme.of(context);
    return new Scaffold(
      body: new Center(
        child: new Stack(
          children: [
            new AnimatedBuilder(
              child: widget.frontWidget,animation: _backScale,builder: (BuildContext context,Widget child) {
                final Matrix4 transform = new Matrix4.identity()
                  ..scale(_backScale.value,1.0);

                return new Transform(
                  transform: transform,alignment: FractionalOffset.center,child: child,);
              },new AnimatedBuilder(
                child: widget.backWidget,animation: _frontScale,Widget child) {
                  final Matrix4 transform = new Matrix4.identity()
                    ..scale(_frontScale.value,1.0);
                  return new Transform(
                    transform: transform,);
                }
            ),],);
  }

  doTheFlip() {
    setState(() {
      if (_controller.isCompleted || _controller.velocity > 0)
        _controller.reverse();
      else
        _controller.forward();
    });
  }
}

final Widget frontWidget = new Container(
  color: Colors.white,height: 180.0,child: new Column(
    children: [
      new Text("Front Side of the card")
    ],);

解决方法

您应该对此代码进行一些更改.

> RootWidget应该是有状态的.将翻转状态存储在那里.
> BackWidget应该是无状态的.它所要做的就是通知RootWidget按下按钮.
> FlipWidget应检测使用didUpdateWidget翻转的更改.
>不要将状态存储到Widget的成员变量中,并且如果可以避免,请避免将mutator方法放在State上…这通常表明您需要将状态存储在窗口小部件树中并通过它与构造函数参数.

在Widget Framework Tour和interactivity tutorial中了解有关StatefulWidget和StatelessWidget的更多信息.

enter image description here

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

void main() {
  runApp(new MaterialApp(
    home: new Container(
      color: Colors.white,child: new RootWidget(),));
}

class RootWidget extends StatefulWidget {
  @override
  _RootWidgetState createState() => new _RootWidgetState();
}

class _RootWidgetState extends State<RootWidget> {
  bool _flipped = false;

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new FlipWidget(
        flipped: _flipped,frontWidget: new Container(
          color: Colors.white,child: new Column(
            children: [
              new Text("Front Side of the card")
            ],backWidget: new BackWidget(
          onPressedButton: () {
            setState(() {
              _flipped = !_flipped;
            });
          },);
  }
}

class BackWidget extends StatelessWidget {
  BackWidget({
    this.onPressedButton,});
  final VoidCallback onPressedButton;

  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 180.0,child:new FlatButton(
        onPressed: onPressedButton,);
  }
}

class FlipWidget extends StatefulWidget {
  FlipWidget({
    @required this.frontWidget,@required this.flipped,});

  final Widget frontWidget;
  final Widget backWidget;
  final bool flipped;

  @override
  _FlipWidgetState createState() => new _FlipWidgetState();
}

class _FlipWidgetState extends State<FlipWidget> with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<double> _frontScale;
  Animation<double> _backScale;

  @override
  void initState() {
    super.initState();
    _controller = new AnimationController(
      vsync: this,duration: const Duration(milliseconds: 1500)
    )..value = widget.flipped ? 1.0 : 0.0;
    _frontScale = new Tween(
      begin: 1.0,);
  }

  @override
  void didUpdateWidget(FlipWidget oldWidget) {
    if (widget.flipped != oldWidget.flipped) {
      if (widget.flipped) {
        _controller.forward();
      } else {
        _controller.reverse();
      }
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new Stack(
          children: [
            new AnimatedBuilder(
              child: widget.frontWidget,);
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读