子类扩展StatelessWidget或StatefulWidget类的类

M20*_*M20 5 flutter

是否可以创建一个扩展了StatelessWidget或StatefulWidget的类的类。

例如:

class MyButton extends StatelessWidget {
final String label;
Button({this.label});
@override
Widget build(BuildContext context) {
    return ButtonExample("label");}
}
Run Code Online (Sandbox Code Playgroud)

然后

class SubmitButton extends MyButton
{
   String label;
   SubmitButton({Key key, this.label}) : super(label: label);

// then somehow extend the parent build and change only the color
// or in case of StatefulWidget change a functionality
}
Run Code Online (Sandbox Code Playgroud)

我尝试在线搜索示例,但没有成功。

Ale*_*din 17

如果您强烈需要扩展已经扩展的小部件,StatefulWidget您可以执行以下操作:

class WidgetFoo extends StatefulWidget {
  final String varFromFoo = 'foo';
  @override
  State<StatefulWidget> createState() => WidgetFooState<WidgetFoo>();
}

// Don't make this class name private (beginning with _) to allow its usage in other modules.
class WidgetFooState <T extends StatefulWidget> extends State<T> {
  String varFromFooState = 'foo state';
  @override
  Widget build(BuildContext context) {
    return Text(getText());
  }

  String getText() {
    return 'WidgetFoo';
  }
}

class WidgetBar extends WidgetFoo {
  @override
  State<StatefulWidget> createState() => _WidgetBarState<WidgetBar>();
}

class _WidgetBarState extends WidgetFooState<WidgetBar> {
  @override
  String getText() {
    return 'WidgetBar, ${varFromFooState}, ${widget.varFromFoo}';
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您实例化它,WidgetBar它将WidgetBar, foo state, foo使用祖先的变量来渲染文本。

这不是在 Flutter 上进行开发的最佳方式,但仍然是对您问题的直接回答。无状态小部件的扩展是类似的。您只需添加返回一些默认值并且可以在继承类中重写的方法。这就是OOP的经典。


Gün*_*uer 10

在Flutter中,组合优先于继承。
小部件不应该扩展,这就是为什么没有示例或教程的原因。

Flutter着重于构图,所包含的窗口小部件库包含许多做得很好的较小的窗口小部件,从而允许它们以多种不同方式组合成自定义窗口小部件。

  • 如果能得到一个关于如何使用组合的代码示例就好了;这与其说是一个答案,不如说是对该方法错误的评论。 (5认同)
  • 然后假设我想通过更改“onTap”方法实现来扩展“BottomNavBar”的功能,但保持所有与样式相关的内容相同。我应该如何将其制作成一个可以在任何地方轻松使用的通用小部件,而无需一一获取“BottomNavBar”的每个属性? (3认同)

Rém*_*let 7

正如Gunter所说的,扑动使用的是继承而不是继承。

官方消息:常见问题解答

Flutter并没有包含每个小部件提供大量参数的功能,而是采用了组合。窗口小部件由较小的窗口小部件构建而成,您可以重用这些小窗口小部件,并以新颖的方式组合以创建自定义窗口小部件。例如,RaisedButton不会将通用按钮小部件归类,而是将Material小部件与GestureDetector小部件组合在一起。Material小部件提供视觉设计,而GestureDetector小部件提供交互设计。

这意味着您应该创建一个较小的小部件然后再使用它,而不是扩展小部件。

一个实际的例子是一个基本按钮:

class MyButton extends StatelessWidget {
  final Color color;

  MyButton({this.color = Colors.grey, Key key}): super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: color,
      child: Text("My Button"),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

然后使用组合重用以创建更特定类型的按钮:

class OutlineButton extends StatelessWidget {
  final Color color;

  OutlineButton({this.color = Colors.grey, Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return DecoratedBox(
      decoration: BoxDecoration(
        border: Border.all(
          color: color,
          width: 2.0,
          style: BorderStyle.solid,
        ),
      ),
      child: MyButton(
        color: color,
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我有一个定义全局样式的 customTextField,然后有一个使用 customTextField 作为样式但需要 TextFormField 的某些属性(如键盘类型)的 emailTextField,该怎么办?无需在 customTextField 中显式传递此属性? (3认同)