dart – Flutter Nested Widget Callback / Async Questions

前端之家收集整理的这篇文章主要介绍了dart – Flutter Nested Widget Callback / Async Questions前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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 Tourinteractivity 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,);
  }
}

猜你在找的Flutter相关文章