Search code examples
flutterdartunityads

How to trigger a function in a stateful widget from another class (when onUnityAdsFinish)?


I have a game screen in a stateful widget that includes a function that lets the player take a step back (undo the previous move). I would like to trigger this function when onUnityAdsFinish() runs from another widget.

Here's the stateful widget on game.dart where the game is played:

class GameScreen extends StatefulWidget {
  @override
  GameScreenState createState() => GameScreenState();
}

class GameScreenState extends State<GameScreen> with SingleTickerProviderStateMixin {

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Container( 
            // game content here
        ),
        MaterialButton(
          child: Text("Tap Here to Watch Ad to Undo Move"),
          onPressed: () => unityBloc.showUnityAd(),
          // (side note: unityBloc is accessable because I have it declared as "final unityBloc = UnityBloc();" higher up the widget tree on app.dart.)
        ),
      ],
    ),                  
  }

  // This is the function I want to call after the ad is finished.
  void undoMove() {
    setState(() {
      // code to undo move
    });
  }
}

When the button is pressed to watch the ad, it calls the showUnityAd() function in my UnityBloc class on unity_bloc.dart:

import 'package:unity_ads_flutter/unity_ads_flutter.dart';

class UnityBloc with UnityAdsListener {
...
  showUnityAd() {
    UnityAdsFlutter.show('rewardedVideo').whenComplete(() => null);
  } // called when undo button is pressed on game.dart

  @override
  void onUnityAdsFinish(String placementId, FinishState result) {
    print("Finished $placementId with $result");
    // here is where I want to call the undoMove() function from game.dart
  }
}

The ad displays perfectly and the print statement in onUnityAdsFinish prints to the console when the ad is finished, but I can't figure out how to call undoMove at that point.

I have spent all day watching tutorials and reading stackoverflows about callbacks and global keys and such, but I'm just still not getting it.

Can someone please help? How can I trigger the undoMove() function on game.dart when onUnityAdsFinish() fires on unity_bloc.dart? (Or is their another/better way to do this?)

Thank you!


Solution

  • You can have a variable that holds a function in the UnityBloc class and pass the undoMove method to the showUnityAd method to assign it to the variable and then you can call it in onUnityAdsFinish method.

    So UnityBloc becomes this:

    class UnityBloc with UnityAdsListener {
      void Function() doOnUnityAdsFinish;
    
      ...
    
      showUnityAd({@required unityAdsFinishFunction}) {
        ...
        doOnUnityAdsFinish = unityAdsFinishFunction;
      } // called when undo button is pressed on game.dart
    
      @override
      void onUnityAdsFinish(String placementId, FinishState result) {
       ...
       doOnUnityAdsFinish?.call(); //Only calls if the function is not null
      }
    }
    

    And you can it in the MaterialButton's onPressed like this:

     MaterialButton(
              child: Text("Tap Here to Watch Ad to Undo Move"),
              onPressed: () => unityBloc.showUnityAd(unityAdsFinishFunction: undoMove ),   
            ),