短剧内容

短剧内容

此章节将演示如何请求在Flutter环境下请求与展示短剧内容

短剧运行流程

运行流程

引入组件

注意

使用短剧内容组件加载时,需要确保 Android 的MainActivity继承io.flutter.embedding.android.FlutterFragmentActivity,Flutter会默认继承 io.flutter.embedding.android.FlutterActivity。详见example/MainActivity

引入ZJTubeAdView组件即可请求信息流广告

/// 短剧视图
class ZJTubeAdView extends StatefulWidget {
  /// 广告位ID
  final String posId;

  /// 宽
  final double width;

  /// 高
  final double height;

  /// 配置
  final ZJTubeAdConfig? config;

  /// 回调
  final Function(ZJEvent ret)? tubeAdListener;

  /// 展示自定义短剧解锁对话框回调
  final TubeAdShowCustomUnlockDialogCallback? showCustomUnlockDialogCallback;

  /// 短剧解锁结果回调
  final TubeAdUnlockCallback? unlockCallback;

  /// 创建成功通知
  final ZJTubeAdViewCreated onCreatedCallback;

  const ZJTubeAdView(this.posId,
      {Key? key,
      required this.width,
      required this.height,
      this.config,
      this.tubeAdListener,
      this.showCustomUnlockDialogCallback,
      this.unlockCallback,
      required this.onCreatedCallback})
      : super(key: key);
}

短剧配置说明

ZJTubeAdConfig.class

属性类型说明默认值
userIdString用户ID""
freeEpisodeCountint每个剧集前N集免费3
unlockEpisodeCountint每次解锁X集2
isHideTitleBarbool是否隐藏剧集主页的TitleBartrue
isDisableUnlockTipDialogbool是否关闭SDK的解锁提示对话框false
isDisableShowTubePanelEntrybool是否关闭短剧播放页的选集入口false
isHideDetailTitleBarbool是否隐藏播放页的titleBarfalse
isHideDetailBottomTitlebool是否隐藏播放页底部的title文案false
isHideDetailBottomDescbool是否隐藏播放页底部的内容描述文案false
isHideDetailPlaySeekbarbool是否隐藏播放页底部的进度条false
lib/widget/zj_tube_ad_view.dart
/// 短剧配置
class ZJTubeAdConfig {
  /// 用户ID
  final String userId;

  /// 每个剧集前N集免费,默认值3
  final int freeEpisodeCount;

  /// 每次解锁X集,默认值2
  final int unlockEpisodeCount;

  /// 是否隐藏剧集主页的TitleBar,默认值true
  final bool isHideTitleBar;

  /// 是否关闭SDK的解锁提示对话框,默认值false
  final bool isDisableUnlockTipDialog;

  /// 是否关闭短剧播放页的选集入口,默认值false
  final bool isDisableShowTubePanelEntry;

  /// 是否隐藏播放页的titleBar,默认值false
  final bool isHideDetailTitleBar;

  /// 是否隐藏播放页底部的title文案,默认值false
  final bool isHideDetailBottomTitle;

  /// 是否隐藏播放页底部的内容描述文案,默认值false
  final bool isHideDetailBottomDesc;

  /// 是否隐藏播放页底部的进度条,默认值false
  final bool isHideDetailPlaySeekbar;

  ZJTubeAdConfig(
      {this.userId = "",
      this.freeEpisodeCount = 3,
      this.unlockEpisodeCount = 2,
      this.isHideTitleBar = true,
      this.isDisableUnlockTipDialog = false,
      this.isDisableShowTubePanelEntry = false,
      this.isHideDetailTitleBar = false,
      this.isHideDetailBottomTitle = false,
      this.isHideDetailBottomDesc = false,
      this.isHideDetailPlaySeekbar = false});
}

短剧内容回调说明

广告加载展示回调

ret.action说明
ZJEventAction.onAdError广告加载失败
ret.code:错误码,非错误事件为0
ret.msg:错误信息,非错误事件为空字符串

自定义短剧解锁对话框回调

ZJTubeAdView配置了isDisableUnlockTipDialog=true时,需要配置TubeAdShowCustomUnlockDialogCallback并根据返回的ZJTubeAdItem对象展示解锁对话框,最后返回用户是否同意观看广告并解锁:

typedef Future<bool> TubeAdShowCustomUnlockDialogCallback(ZJTubeAdItem adItem);

ZJTubeAdItem

ZJTubeAdItem.class

属性类型说明默认值
idString视频唯一ID""
positionint当前位置,从0开始0
videoDurationint视频时长0
authorIdString作者ID""
authorNameString作者鸣潮""
tubeIdint剧场ID0
tubeNameString剧场鸣潮""
episodeNumberint剧集序号0
totalEpisodeCountint总剧集数0
playCountint观看次数0
coverUrlString封面图""
isFinishedbool是否已完结false
isLockedbool是否锁定false
freeEpisodeCountint短剧前N集免费0
unlockEpisodeCountint每次解锁X集短剧0
lib/widget/zj_tube_ad_view.dart
/// 短剧对象
class ZJTubeAdItem {
  /// 视频唯一ID
  String id = "";

  /// 当前位置,从0开始
  int position = 0;

  /// 视频时长
  int videoDuration = 0;

  /// 作者ID
  String authorId = "";

  /// 作者鸣潮
  String authorName = "";

  /// 剧场ID
  int tubeId = 0;

  /// 剧场鸣潮
  String tubeName = "";

  /// 剧集序号
  int episodeNumber = 0;

  /// 总剧集数
  int totalEpisodeCount = 0;

  /// 观看次数
  int playCount = 0;

  /// 封面图
  String coverUrl = "";

  /// 是否已完结
  bool isFinished = false;

  /// 是否锁定
  bool isLocked = false;

  /// 短剧前N集免费
  int freeEpisodeCount = 0;

  /// 每次解锁X集短剧
  int unlockEpisodeCount = 0;
}

短剧解锁结果回调

ZJTubeAdViewunlockCallback类型为TubeAdUnlockCallback,会在解锁广告请求失败或解锁成功时回调,包含当次解锁的结果及错误时的错误信息:

typedef void TubeAdUnlockCallback(bool isSuccess, int errCode, String? errMsg);

创建成功通知

ZJTubeAdViewonCreatedCallback类型为ZJTubeAdViewCreated,会在组件成功创建后返回一个ZJTubeAdViewController对象,用于配置解锁短剧所需的广告位ID及控制组件的显示和隐藏。

typedef void ZJTubeAdViewCreated(ZJTubeAdViewController controller);

ZJTubeAdViewController

ZJTubeAdViewController包含以下方法:

方法说明
hide()隐藏组件
show()显示组件
setUnlockAdPosId(String posId)配置解锁时的广告位ID,仅支持激励广告和插屏
onResume()通知SDK页面恢复

接入示例

example/lib/ad/tube_ad.dart
child: ZJTubeAdView(
  posId,
  width: double.infinity,
  height: double.infinity,
  config: ZJTubeAdConfig(
      userId: TestPosId.testUserId, isHideTitleBar: true),
  // 禁用SDK自带的解锁对话框时,需要展示自定义解锁对话框并返回用户是否同意的状态
  showCustomUnlockDialogCallback: _showCustomUnlockDialog,
  // 短剧解锁结果回调
  unlockCallback: _onUnlockCallback,
  onCreatedCallback: _onTubeAdViewCreated,
  tubeAdListener: (ret) {
    if (ret.action == ZJEventAction.onAdError) {
      Fluttertoast.showToast(msg: "视频内容错误:${ret.msg}");
      if (kDebugMode) {
        print("${ret.action}:${ret.code}-${ret.msg}");
      }
      _reset();
    }
  },
)

  /// 展示短剧组件到容器中
  void _show() {
    if (controller == null) {
      setState(() {
        showTubeView = true;
      });
    } else {
      controller!.show();
    }
  }

  /// 隐藏短剧组件
  void _hide() {
    if (controller == null) {
      Fluttertoast.showToast(msg: "还未加载成功");
    } else {
      // 隐藏
      controller!.hide();
    }
  }

 /// 禁用SDK自带的解锁对话框时,需要展示自定义解锁对话框并返回用户是否同意的状态
  Future<bool> _showCustomUnlockDialog(ZJTubeAdItem adItem) async {
    Completer<bool> completer = Completer();

    /// 在展示自定义解锁对话框后回调结果
    completer.complete(Random().nextBool());  // 此处模拟用户随机同意/取消解锁
    return completer.future;
  }

  /// 短剧解锁结果回调
  /// 成功时code==0,msg==null
  /// 失败时code!=0,msg!=null
  /// 失败事件不一定触发,成功事件一定触发
  void _onUnlockCallback(bool isSuccess, int errCode, String? errMsg) {
    if (isSuccess) {
      Fluttertoast.showToast(msg: "解锁成功");
    } else {
      Fluttertoast.showToast(msg: "解锁失败[$errCode-$errMsg]");
    }
  }

  /// 以Widget加载时的组件控制器
  void _onTubeAdViewCreated(ZJTubeAdViewController controller) {
    this.controller = controller;
    // 在创建视图成功后,需要配置解锁需要的广告位ID(仅支持激励广告和插全屏广告)
    this.controller!.setUnlockAdPosId(Random().nextBool()
        ? TestPosId.rewardVideoPosId
        : TestPosId.interstitialPosId);
  }