9

I'm in need to write an extension for Flutter's State<T extends StatefulWidget> so I can use a function in all of my States, let's say showSnackBar("Hello world", 5). I tried writing a mixin

mixin BaseState on State<ProfileScreen> {
  final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();

  void showSnackBar(String text) {
    setState(() {
      scaffoldKey.currentState.showSnackBar(new SnackBar(
          content: new Row(
            children: <Widget>[
              new CircularProgressIndicator(),
              new Text(text == null ? "  Logging in" : "      $text")
            ],
          )));
    });
  }

  void hideSnackBar() {
    setState(() {
      scaffoldKey.currentState.hideCurrentSnackBar();
    });
  }
}

As you can see, it is now mixed on State<ProfileScreen>. It's a problem because I only can use this mixin in class ProfileScreenState extends State<ProfileScreen>. Without the type notation I end up with an error:

error: The class 'ProfileScreenState' cannot implement both 'State<ProfileScreen>' and 'State<StatefulWidget>' because the type arguments are different. (conflicting_generic_interfaces at [mobile] lib/Screens/profile.dart:17)
error: Type parameters could not be inferred for the mixin 'BaseState' because no type parameter substitution could be found matching the mixin's supertype constraints (mixin_inference_no_possible_substitution at [mobile] lib/Screens/profile.dart:17)

I tried to Google a lot, seen questions like these but without a success.

And yes I know composition is preferred over inheritance in Flutter, but I think this is a thing I don't know I would make work with composition and I feel it will be OK with inheritance.

Martin.
  • 10,494
  • 3
  • 42
  • 68

2 Answers2

18

I think you are looking for something like https://github.com/flutter/flutter/blob/3fbd140e77601686acb336cd2af2838d03ba0572/packages/flutter/lib/src/widgets/ticker_provider.dart#L155

mixin BaseState<T extends StatefulWidget> on State<T> {
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I was very close with `mixin BaseState on State {`. Thanks a lot! Anyway, what in case I would like to, at some point, mixin it into StatelessWidget, is there a quick trick to accept that as well? – Martin. Feb 10 '19 at 15:43
  • `mixin BaseStateless on StatelessWidget {` or `mixin BaseStateless on T {` should do – Günter Zöchbauer Feb 10 '19 at 15:54
  • that is a mixing for Stateless, what if I want to share a functionality for both StatefulWidget and StatelessWidget in one mixin? Does that make sense? – Martin. Feb 10 '19 at 15:56
  • I mean something like `mixin BaseState on State {` – Martin. Feb 10 '19 at 15:58
  • I think in this case you'd need to remove `on X...` – Günter Zöchbauer Feb 10 '19 at 16:00
  • That does cut off the possibility to use the functions from StatelessWidget and StatefulWidget. It's true tho that it probably won't make any sense since StatefulWidget has setState and StatelessWidget has not – Martin. Feb 10 '19 at 16:02
  • They `State` and `StatelessWidget` do not have a common interface so this can't work with the same mixin. – Günter Zöchbauer Feb 10 '19 at 16:13
0

I do something like;

mixin BaseState{ .... }

and it is working, but I don't know after effects.

leylekseven
  • 687
  • 7
  • 15