📺 短剧详情

介绍

越来越多的客户有自定义详情的需求,包括解锁弹窗、标题栏、底部信息栏、选集面板等,所以推出了详情页 Widget 组件,有如下特点:

  • 可嵌入任意 Flutter 页面
  • 可进行高度自定义 UI 和逻辑
  • 配合获取短剧信息,可完全由 Flutter 开发一套 2 端都适配了(iOS 和 Android)

示例图片

下面全是纯 Flutter 自定义页面,可通过体验示例应用

剧场组件 滑滑流组件 详情组件 解锁弹窗

短剧组件

剧场组件

example/pages/drama_detail.dart
1/// [controller] 视频控制器
2/// [channelType] 顶部频道类型[VideoDrawParams]
3/// [width] View 的宽度
4/// [height] View 的高度
5/// [detailFree] 免费集数
6/// [unlockCount] 解锁集数
7/// [hideTopInfo] 是否隐藏顶部信息
8/// [setTopOffset] 顶部信息偏移
9/// [hideBottomInfo] 是否隐藏底部信息[滑滑流]
10/// [setBottomOffset] 底部信息偏移[滑滑流]
11/// [hideLikeButton] 是否隐藏点赞按钮[滑滑流]
12/// [hideFavorButton] 是否隐藏收藏按钮[滑滑流]
13/// [hideEnter] 是否隐藏进入(下一集)按钮[滑滑流]
14/// [showChangeBtn] 是否显示换一换按钮[剧场]
15TheaterWidget(
16    controller: [播放控制器看下面👇],
17    width: 375,
18    height: 812,
19    channelType: VideoDrawParams.drawChannelTypeRecommend,
20    hideTopInfo: true,
21    setTopOffset: 54,
22    hideBottomInfo: true,
23    theaterListener: TheaterListener(
24        onOpenDetail: (drama) {
25          // 打开短剧详情
26          toDetail(context, drama);
27        },
28      ),
29  )

不同的频道类型,展示的内容不同,都是用剧场组件类呈现

  • drawChannelTypeRecommend:推荐(滑滑流)
  • drawChannelTypeTheater:剧场
  • drawChannelTypeRecommendTheater:短剧:推荐+剧场(滑滑流)

详情组件

example/pages/drama_detail.dart
1/// [controller] 视频控制器
2/// [unlockFlowListener] 解锁流程监听
3/// [videoPlayListener] 视频播放监听器
4/// [width] View 的宽度
5/// [height] View 的高度
6/// [id] 短剧 ID
7/// [index] 集数
8/// [groupId] 分组 ID
9/// [detailFree] 免费集数
10/// [unlockCount] 解锁集数
11/// [hideTopInfo] 是否隐藏顶部信息
12/// [setTopOffset] 顶部信息偏移
13/// [hideBottomInfo] 是否隐藏底部信息
14/// [setBottomOffset] 底部信息偏移
15/// [hideRewardDialog] 是否隐藏奖励对话框
16/// [hideMore] 是否隐藏更多
17/// [hideCellularToast] 是否隐藏流量提示
18DramaWidget(
19    controller: [播放控制器看下面👇],
20    width: 375,
21    height: 812,
22    id: widget.drama.id,
23    index: widget.drama.index,
24    unlockFlowListener: [解锁流程监听看下面👇],
25    videoPlayListener: [播放流程监听看下面👇],
26  )
💡 小提示
  • 要使用组件需修改 Android 启动页面继承 FlutterFragmentActivity
  • Java 版:
example/android/app/src/main/java/com/zero/flutter_adcontent_example/MainActivity.java
1import io.flutter.embedding.android.FlutterActivity;
2import io.flutter.embedding.android.FlutterFragmentActivity;
3
4public class MainActivity extends FlutterFragmentActivity {
5}
  • Kotlin 版:
example/android/app/src/main/kotlin/com/zero/flutter_adcontent_example/MainActivity.kotlin
1import io.flutter.embedding.android.FlutterActivity
2import io.flutter.embedding.android.FlutterFragmentActivity;
3
4class MainActivity: FlutterFragmentActivity () {
5}

播放控制器

example/pages/drama_detail.dart
1/// 在 initState 中初始化,并传递给组件
2late ProVideoController controller;
3
4
5void initState() {
6  controller = ProVideoController();
7}
8
9
10Widget build(BuildContext context) {
11  return Scaffold(
12      body: DramaWidget(
13        controller: controller,
14        ...
15        )
16  )
17}

暂停&继续

example/pages/drama_detail.dart
controller.pause();
controller.resume();

设置当前播放集数

example/pages/drama_detail.dart
/// [index] 集数
controller.setCurrentIndex(currentIndex);

打开选集面板

example/pages/drama_detail.dart
controller.openDramaGallery();

打开更多弹窗

example/pages/drama_detail.dart
controller.openMoreDialog();

解锁剧集

example/pages/drama_detail.dart
/// [id] 短剧ID
/// [lockSet] 锁集数
/// [cancel] 是否取消
controller.unLock(2324,2,false);

剧场监听

example/pages/drama_detail.dart
1TheaterListener(
2    onOpenDetail: (drama) {
3      // 打开短剧详情
4      toDetail(context, drama);
5    },
6  )

解锁流程监听

example/pages/drama_detail.dart
1UnlockFlowListener(
2      unlockFlowStart: (Drama drama) {
3        // 解锁流程开始
4        showUnlockDialog(drama);
5      },
6      unlockFlowEnd: (Drama drama, int? errCode, String? errMsg) {
7        // 解锁流程结束
8        print(
9            'unlockFlowEnd: ${drama.title} errCode:$errCode errMsg:$errMsg');
10        if (errCode != null) {
11          // 解锁失败,返回上一集
12          backIndex();
13        } else {
14          // 解锁成功
15        }
16      },
17    )

解锁弹窗自定义

example/pages/drama_detail.dart
1/// 返回上一集
2void backIndex() {
3  controller.setCurrentIndex(currentIndex);
4}
5
6/// 解锁短剧
7Future<void> unLockDrama(Drama drama, bool cancel) async {
8  controller.unLock(drama.id, 2, cancel);
9}
10
11/// 显示 Dialog
12Future<void> showUnlockDialog(Drama drama) async {
13  showDialog(
14    context: context,
15    barrierDismissible: false,
16    builder: (context) => UnlockDialog(
17      title: '${drama.title} ',
18      indexText: '第${drama.index}集',
19      unlockText: '免费解锁 2 集',
20      tipText: "解锁还能提高红包奖励哦~",
21      onClose: () {
22        Navigator.pop(context);
23        unLockDrama(drama, true);
24      },
25      onUnlock: () {
26        Navigator.pop(context);
27        unLockDrama(drama, false);
28      },
29    ),
30  );
31}

短剧播放监听

example/pages/drama_detail.dart
1VideoPlayListener(
2      onDJXPageChange: (Drama drama) {
3        // 视频切换
4        print(
5            'VideoPlayListener onDJXPageChange: ${drama.id}:${drama.title}:${drama.index}');
6        setState(() {
7          newIndex = drama.index;
8        });
9      },
10      onDJXVideoPlay: (Drama drama) {
11        // 视频播放开始
12        print(
13            'VideoPlayListener onDJXVideoPlay: ${drama.id}:${drama.title}:${drama.index}');
14        currentIndex = drama.index;
15      },
16      onDJXVideoPause: (Drama drama) {
17        // 视频暂停
18        print(
19            'VideoPlayListener onDJXVideoPause:  ${drama.id}:${drama.title}:${drama.index}');
20      },
21      onDJXVideoContinue: (Drama drama) {
22        // 视频继续
23        print(
24            'VideoPlayListener onDJXVideoContinue: ${drama.id}:${drama.title}:${drama.index}');
25      },
26      onDJXVideoCompletion: (Drama drama) {
27        // 视频播放完成
28        print(
29            'VideoPlayListener onDJXVideoCompletion: ${drama.id}:${drama.title}:${drama.index}');
30      },
31      onDJXVideoOver: (Drama drama) {
32        // 视频结束
33        print(
34            'VideoPlayListener onDJXVideoOver: ${drama.id}:${drama.title}:${drama.index}');
35      },
36      onDJXVideoClose: () {
37        // 视频关闭
38        print('VideoPlayListener onDJXVideoClose');
39      },
40      onDJXSeekTo: (duration) {
41        // 拖动进度
42        print("VideoPlayListener onDJXSeekTo:$duration");
43      },
44      onDurationChange: (duration) {
45        // 播放进度
46        print("VideoPlayListener onDurationChange:$duration");
47      },
48    )

监听场景说明

example/pages/drama_detail.dart
1VideoPlayListener(
2      onDJXPageChange: (Drama drama) {
3        // 视频切换,这是当前最新一集短剧,用于渲染集数等信息使用
4        setState(() {
5          newIndex = drama.index;
6        });
7      },
8      onDJXVideoPlay: (Drama drama) {
9        // 视频播放开始,未解锁的不会触发,所以这里用于解锁失败返回上一集的记录值
10        currentIndex = drama.index;
11      },
12    )