0

我在一个有状态的小部件中有一个游戏屏幕,其中包括一个让玩家后退一步(撤消上一步)的功能。我想在 onUnityAdsFinish() 从另一个小部件运行时触发此功能。

这是游戏运行的 game.dart 上的有状态小部件:

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

当按下按钮观看广告时,它会在 unity_bloc.dart 上的 UnityBloc 类中调用 showUnityAd() 函数:

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

广告完美显示,并且 onUnityAdsFinish 中的打印语句在广告完成后打印到控制台,但我不知道此时如何调用 undoMove。

我整天都在看教程和阅读关于回调和全局键等的stackoverflows,但我仍然没有得到它。

有人可以帮忙吗?当 onUnityAdsFinish() 在 unity_bloc.dart 上触发时,如何触发 game.dart 上的 undoMove() 函数?(或者他们是另一种/更好的方法吗?)

谢谢!

4

2 回答 2

1

UnityBloc您可以在类中拥有一个包含函数的变量,并将该方法传递undoMove给该showUnityAd方法以将其分配给该变量,然后您可以在 onUnityAdsFinish 方法中调用它。

所以UnityBloc变成了这样:

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

你可以像MaterialButton这样onPressed

 MaterialButton(
          child: Text("Tap Here to Watch Ad to Undo Move"),
          onPressed: () => unityBloc.showUnityAd(unityAdsFinishFunction: undoMove ),   
        ),
于 2021-02-06T00:40:13.950 回答
0

最简单的方法是全局/静态变量(回调)或 ValueNotifier/Stream。也许,一种更简洁的方法是一些具有依赖注入功能的包,如(getget_it)。

class UnityBloc with UnityAdsListener {
  /// pass a callback into the constructor.
  /// Function<String,FinishState> onAdCompleted ;
  /// UnityBloc([this.onAdCompleted]);

  /// easier approach, not very "flexible".
  static Function<String,FinishState> onAdCompleted ;

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

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


class GameScreenState extends State<GameScreen> with SingleTickerProviderStateMixin {

  @override
  void initState(){
     super.initState();
     UnityBloc.onAdCompleted = _onAddCompleted;
  }

  @override
  void dispose(){
     super.dispose();
     if( UnityBloc.onAdCompleted == _onAddCompleted) {
         UnityBloc.onAdCompleted = null;
     }
  }

  void _onAddCompleted(String placementId, FinishState result) 
    => print("Finished $placementId with $result"); 

  @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
    });
  }
}
于 2021-02-06T00:45:11.653 回答