Tay*_*own 5 dart flutter flutter-layout
我一直在读像这篇文章这样的东西解释 Flutter 如何更喜欢组合而不是继承。虽然我部分理解原因,但我质疑在这种做法变得冗长的情况下该怎么做。另外,在 Flutter 的内部代码中,内置组件到处都有继承。所以从哲学上来说,一定有什么场景是可以的。
考虑这个例子(基于Widget我制作的真实例子):
class MyFadingAnimation extends StatefulWidget {
final bool activated;
final Duration duration;
final Curve curve;
final Offset transformOffsetStart;
final Offset transformOffsetEnd;
final void Function()? onEnd;
final Widget? child;
const MyFadingAnimation({
super.key,
required this.activated,
this.duration = const Duration(milliseconds: 500),
this.curve = Curves.easeOut,
required this.transformOffsetStart,
this.transformOffsetEnd = const Offset(0, 0),
this.onEnd,
this.child,
});
@override
State<MyFadingAnimation> createState() => _MyFadingAnimationBuilder();
}
class _MyFadingAnimationBuilder extends State<MyFadingAnimation> {
@override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: widget.duration,
curve: widget.curve,
transform: Transform.translate(
offset: widget.activated ?
widget.transformOffsetStart : widget.transformOffsetEnd,
).transform,
onEnd: widget.onEnd,
child: AnimatedOpacity(
duration: widget.duration,
curve: widget.curve,
opacity: widget.activated ? 1 : 0,
child: widget.child
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
目标MyFadingAnimation是同时执行平移和不透明动画Widget。伟大的!
现在,假设我想为此小部件创建一些“快捷方式”或“别名”,例如MyHorizontalAnimation水平淡入或MyVerticalAnimation垂直淡入。使用组合,您必须创建如下内容:
class MyHorizontalAnimation extends StatelessWidget {
final bool activated;
final Duration duration;
final Curve curve;
final double offsetStart;
final void Function()? onEnd;
final Widget? child;
const MyHorizontalAnimation({
super.key,
required this.activated,
this.duration = const Duration(milliseconds: 500),
this.curve = Curves.easeOut,
required this.offsetStart,
this.onEnd,
this.child,
});
@override
Widget build(BuildContext context) {
return MyFadingAnimation(
activated: activated,
duration: duration,
curve: curve,
transformOffsetStart: Offset(offsetStart, 0),
onEnd: onEnd,
child: child,
);
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎非常冗长。所以我最初的想法是“好吧,也许我应该尝试延长课程……”
class MyHorizontalAnimation extends MyFadingAnimation {
final double offsetStart;
MyHorizontalAnimation({
super.key,
required super.activated,
super.duration,
super.curve,
this.offsetStart,
super.onEnd,
super.child,
}) : super(
transformOffsetStart: Offset(offsetStart, 0),
);
}
Run Code Online (Sandbox Code Playgroud)
对我来说这看起来更干净。另外,它还有一个额外的好处,如果我向 中添加功能/属性MyFadingAnimation,它几乎会自动集成到MyHorizontalAnimation(除了必须添加之外super.newProp)。使用组合方法,我必须添加一个新属性,可能复制/维护默认值,将其添加到构造函数中,当我完成时,感觉就像一件苦差事。
不过,我使用继承的主要问题(这可能真的很小)是,const除了我的基本小部件MyFadingAnimation. 再加上继承的强烈阻碍,让我觉得有更好的方法。
因此,总而言之,这是我的两个问题:
const Widget重定向到其他“base” Widget?我不会担心重定向构造函数中缺少 a const- 毕竟,组合示例的const内部MyFadingAnimation构造中也缺少 a 。不可能使用const Offset未知的整数参数来创建 a,因此这是不可避免的语言限制。
关于组合与继承的主题,还有另一种适合您的用例的解决方案:基类中的辅助构造函数。这种模式在整个框架中使用 -SizedBox例如,看看 。
但请注意,这种风格在默认参数值方面确实引入了一些重复性。
class MyFadingAnimation extends StatefulWidget {
final bool activated;
final Duration duration;
final Curve curve;
final Offset transformOffsetStart;
final Offset transformOffsetEnd;
final void Function()? onEnd;
final Widget? child;
const MyFadingAnimation({
super.key,
required this.activated,
this.duration = const Duration(milliseconds: 500),
this.curve = Curves.easeOut,
required this.transformOffsetStart,
this.transformOffsetEnd = const Offset(0, 0),
this.onEnd,
this.child,
});
MyFadingAnimation.horizontal({
super.key,
required this.activated,
this.duration = const Duration(milliseconds: 500),
this.curve = Curves.easeOut,
required double offsetStart,
this.onEnd,
this.child,
}) : transformOffsetStart = Offset(offsetStart, 0),
transformOffsetEnd = const Offset(0, 0);
@override
State<MyFadingAnimation> createState() => _MyFadingAnimationBuilder();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
649 次 |
| 最近记录: |