Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to make a funtion not overridable in Flutter? [duplicate]

Tags:

flutter

dart

I have a class InfoScreen which extends a BaseInfoScreen. Inside that BaseInfoScreen there is a Widget body();, which all childs can override. There is also a Widget banner();, which is implemented in BaseInfoScreen, and I inherited widgets to use it but not override it (as it has to be the same for all screens). Is there a way I can tell Widget banner(); not to be overridable? I tried adding final and const to the function but it won't let me.

Full Code example:

BaseInfoScreen

  abstract class BaseInfoScreen extends StatefulWidget {
    final String title;
  
    BaseInfoScreen({
      Key key,
      this.title,
    }) : super(key: key);
  }
  
  abstract class BaseInfoScreenState<Page extends BaseInfoScreen>
      extends State<BaseInfoScreen> {
  
    bool showFabMenu() => true;
  }
  
  mixin BaseScreen<Page extends BaseInfoScreen> on BaseInfoScreenState<Page> {
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: CoolAppBar(
          title: widget.title,              
        ),
        drawer: Container(
          width: 290,
          child: Drawer(
            child: DrawerMenu(),
          ),
        ),
        body: body(),
        floatingActionButton: showFabMenu() ? FabMenu() : null,
      );
    }
    
  //This should be overridable
  Widget body();

  //This should be usable by widgets that inherit from BaseInfoScreen, but not override it.
  Widget banner() {
    return Container(
      color: Colors.black12,
      padding: const EdgeInsets.all(20),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          widget.bannerIconAsset != null
              ? Container(
                  child: Image.asset(
                    widget.bannerIconAsset,
                    width: 36,
                    height: 36,
                    filterQuality: FilterQuality.high,
                    color: Colors.white,
                  ),
                )
              : Container(
                  child: Icon(
                    widget.bannerIconData,
                    size: 36,
                    color: Colors.white,
                  ),
                ),
          SizedBox(width: 20),
          Container(
            constraints: BoxConstraints(
                maxWidth: MediaQuery.of(context).size.width * 0.7),
            child: FittedBox(
              fit: widget.bannerTitle.length > 10
                  ? BoxFit.fitWidth
                  : BoxFit.none,
              child: Text(
                widget.bannerTitle,
                style: TextStyle(
                  fontSize: 28,
                  fontFamily: 'Raleway',
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }    

InfoScreen

class InfoScreen extends BaseInfoScreen {
  final String title;

  InfoScreen({
    this.title,
  }) : super(
          title: title,
        );

  @override
  _InfoScreenState createState() =>
      _InfoScreenState();
}

class _InfoScreenState extends BaseInfoScreenState<InfoScreen> with BaseScreen
{
  _InfoScreenState();

  @override
  Widget body() {
     return Column(
       children: [
         //Here I call banner()
         banner(),
         //Here I declare other widgets that are part of the body
       ],
     );
  }
}

I tried to strip down the code as much as possible to keep it simple. Maybe the answer is simply "no, it's not possible", but I couldn't find anything online.

like image 906
Guido Spadavecchia Avatar asked Nov 02 '25 08:11

Guido Spadavecchia


1 Answers

You can do that thanks to the nonVirtual annotation of the meta package:

import 'package:meta/meta.dart';

void main() {
  B().p();
}

class A {
  @nonVirtual
  void p() => print('A');
}

class B extends A {
  void p() => print('B');
}

By default the invalid_override_of_non_virtual_member is just an info. You might want to enforce it strongly by modifying the analysis_options.yaml file at the root of your project:

analyzer:
  errors:
    invalid_override_of_non_virtual_member: error

Check here for more info on customizing Dart static analysis.

like image 115
Thierry Avatar answered Nov 03 '25 21:11

Thierry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!