Subclass a class that extends StatelessWidget or StatefulWidget class

If you strongly need to extend a widget that already extends StatefulWidget you can do something like this:

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}';
  }
}

If you instantiate the WidgetBar it will render the WidgetBar, foo state, foo text, using variables from ancestors.

This is not the best way to develop on Flutter but still, that's a direct answer to your question. The extension of stateless widgets is similar. You just add methods that return some default values and that can be overridden in an inherited class. That's the classics of OOP.


As stated by Gunter, flutter uses composition over inheritance.

Official source : flutter faq

Rather than having each widget provide a large number of parameters, Flutter embraces composition. Widgets are built out of smaller widgets that you can reuse and combine in novel ways to make custom widgets. For example, rather than subclassing a generic button widget, RaisedButton combines a Material widget with a GestureDetector widget. The Material widget provides the visual design and the GestureDetector widget provides the interaction design.

This means that instead of extending a Widget, you should create a smaller one and then reuse it.

A practical example would be a base button :

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"),
    );
  }
}

Then reused using composition to create a more specific type of button :

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,
      ),
    );
  }
}

In Flutter composition is preferred over inheritance.
Widgets are not supposed to be extended, this is why there are no examples or tutorials how to do it.

Flutter has a strong focus on composition and the included widget library contains a lot of smaller widgets that do one thing well, that allow to compose them into custom widgets in many different ways.

Tags:

Flutter