【问题标题】:How to share common parameters between two widgets?如何在两个小部件之间共享公共参数?
【发布时间】:2020-05-09 11:32:45
【问题描述】:

我有一个以下小部件,如果animated = true 呈现AnimatedContainer 并且如果animated = false 呈现Container

animated
        ? AnimatedContainer(
            duration: duration,
            decoration: decoration,
            child: child,
            margin: margin,
            padding: padding,
          )
        : Container(
            decoration: decoration,
            child: child,
            margin: margin,
            padding: padding,
          );

如您所见,这两个小部件共有四个参数。有没有一种方法可以将参数存储在变量中并作为一个变量在它们之间传递?所以像:

var params = (
  decoration: decoration,
  child: child,
  margin: margin,
  padding: padding,
);

animated
        ? AnimatedContainer(
            duration: duration,
            ...params,
          )
        : Container(params);

【问题讨论】:

  • 如果没有动画,您是否尝试仅使用持续时间为零的 AnimatedContainer?
  • 我相信你不能那样定义小部件的属性。您要么遵循上面的建议,要么像在自己的代码中那样做。定义变量并在每个 Widget 中重复使用它们。

标签: flutter dart


【解决方案1】:

您可以为此使用 bloc。 制作一个 StreamController 并将两个小部件包装在 StreamBuilder 中。 现在,当您想要更新值时,只需将值添加到 StreamSink。

代码:

class AnimationBloc extends Bloc {
  StreamController _animationController = StreamController<bool>.broadcast();
  Stream get animationStream => _animationController.stream;
  StreamSink get animationStreamSink => _animationController.sink;
  @override
  void dispose() {
    _animationController.close();
  }
}

块在哪里:

abstract class Bloc {
  void dispose();
}

现在用 StreamBuilder 包装小部件

StreamBuilder<bool>(
   initialData: false,
   stream: AnimationBloc.animationStream,
   builder: (BuildContext context,
             AsyncSnapshot<String> snapshot) {
             return 
              snapshot.data
                ? AnimatedContainer(
                   duration: duration,
                   decoration: decoration,
                   child: child,
                   margin: margin,
                   padding: padding,
                 )
                : Container(
                   decoration: decoration,
                   child: child,
                   margin: margin,
                   padding: padding,
                );
             },
  ),

[对其他小部件执行相同操作] 当您需要将布尔值 animated 更新为 true 时,只需将其放入 AnimationBloc.animationStreamSink.add(true) 即可在两个小部件中进行更新。

【讨论】:

    【解决方案2】:

    您可以制作自己的小部件,返回动画小部件或容器,但将您定义的一些抽象数据类型作为参数,包括装饰、填充、子元素等。

    这是一个例子:

    import 'package:flutter/material.dart';
    
    class MyAnimatedContainer extends StatelessWidget {
      final Duration duration;
      final Params params;
    
      MyAnimatedContainer({this.duration = Duration(seconds:1), this.params}) : assert(params != null);
      @override
      Widget build(BuildContext context) {
        return AnimatedContainer(
          duration: duration,
          child: params.child,
          decoration: params.decoration,
          padding: params.padding,
        );
      }
    }
    
    class MyContainer extends StatelessWidget {
      final Params params;
    
      MyContainer(this.params) : assert(params != null);
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: params.child,
          decoration: params.decoration,
          padding: params.padding,
        );
      }
    }
    
    
    class Params {
      final Widget child;
      final Decoration decoration;
      final EdgeInsetsGeometry padding;
    
      Params({this.child, this.decoration, this.padding = const EdgeInsets.all(12.0)}) : assert(child != null);
    }
    

    所以你可以以某种方式定义你的参数:

    Params containerParams = Params(child: SomeWidget(), decoration: Decoration(...), padding: const EdgeInsets.all(12.0));
    

    然后使用该 params 对象创建您的自定义容器小部件:

    animated ? 
    MyAnimatedContainer(duration: Duration(seconds: 1), params: containerParams) :
    MyContainer(containerParams);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 2011-08-20
      • 2020-04-07
      • 2013-02-25
      • 1970-01-01
      • 2010-11-29
      • 2013-02-08
      相关资源
      最近更新 更多