🎬 短剧模块
版本 PanGrowth

🎬 短剧滑滑流

短剧滑滑流提供类似抖音的竖向滑动播放体验,支持推荐/剧场频道、广告解锁、播放控制等完整能力。插件同时提供 NativeView 组件API 控制 两条集成路径。

🚪 接入方式概览

方式推荐场景实现特点
NativeView 组件(推荐)Flutter 页面内嵌滑滑流内容,追求最少代码使用 DramaSwipeFlowNativeView,自动管理创建/销毁,可配合 DramaSwipeFlowControllerDramaSwipeFlowListener
API 调用需要在原生 Activity/ViewController 展示或精确控制生命周期使用 createDramaSwipeFlow / showDramaSwipeFlow / hideDramaSwipeFlow / destroyDramaSwipeFlow 主动控制

注意:两种方式的配置对象不同:

  • NativeView 方式使用 DramaSwipeFlowConfig
  • API 方式使用 DramaSwipeConfig

✅ 方式一:DramaSwipeFlowNativeView(推荐)

DramaSwipeFlowNativeView 通过 PlatformView 内嵌原生滑滑流,Flutter 层像普通 Widget 一样使用。

基础示例

import 'package:flutter/material.dart';
import 'package:pangrowth_content/pangrowth_content.dart';

class DramaSwipeFlowPage extends StatelessWidget {
  const DramaSwipeFlowPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: DramaSwipeFlowNativeView(
        config: const DramaSwipeFlowConfig(
          channelType: 1,   // 推荐频道
          detailFree: 5,    // 免费 5 集
          unlockCount: 1,   // 每次解锁 1 集
          autoPlay: true,   // 自动播放下一集
        ),
      ),
    );
  }
}

结合 DramaSwipeFlowListener

使用 DramaSwipeFlowListener 监听滑滑流生命周期事件:

DramaSwipeFlowNativeView(
  config: const DramaSwipeFlowConfig(
    channelType: 1,
    detailFree: 5,
    unlockCount: 1,
  ),
  listener: DramaSwipeFlowListener(
    onSwipeFlowReady: (swipeFlowId) {
      debugPrint('滑滑流就绪: $swipeFlowId');
    },
    onSwipeFlowError: (error) {
      debugPrint('滑滑流错误: $error');
    },
    onSwipeFlowDisposed: () {
      debugPrint('滑滑流已销毁');
    },
    onOpenDetail: (drama) {
      debugPrint('打开短剧详情: ${drama.title}');
      // 可在此处拦截并导航到自定义详情页
    },
  ),
)

结合 DramaSwipeFlowController

当需要在 TabBar 切换等场景控制暂停/恢复时,使用 DramaSwipeFlowController:

class DramaTabPage extends StatefulWidget {
  const DramaTabPage({super.key});

  @override
  State<DramaTabPage> createState() => _DramaTabPageState();
}

class _DramaTabPageState extends State<DramaTabPage>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
  final _swipeFlowController = DramaSwipeFlowController();

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);

    // 监听Tab切换,自动暂停/恢复
    _tabController.addListener(() {
      if (_tabController.index == 1) {
        _swipeFlowController.resume(); // 切换到滑滑流Tab,恢复播放
      } else {
        _swipeFlowController.pause();  // 切换走,暂停播放
      }
    });
  }

  @override
  void dispose() {
    _swipeFlowController.dispose();
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _tabController,
          tabs: const [
            Tab(text: '首页'),
            Tab(text: '追剧'), // 滑滑流Tab
            Tab(text: '我的'),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          const Center(child: Text('首页')),
          DramaSwipeFlowNativeView(
            config: const DramaSwipeFlowConfig(
              channelType: 3, // 推荐+剧场双频道
              detailFree: 5,
              unlockCount: 1,
            ),
            controller: _swipeFlowController,
          ),
          const Center(child: Text('我的')),
        ],
      ),
    );
  }
}

配置参数:DramaSwipeFlowConfig

参数类型默认值说明
频道配置
channelTypeint1频道类型:<br/>• 1 - 仅推荐频道<br/>• 2 - 仅剧场频道<br/>• 3 - 推荐+剧场双频道
解锁配置
detailFreeint5免费观看集数
unlockCountint1每次观看广告解锁的集数
unlockAdModeint0解锁广告模式:<br/>• 0 - SDK默认解锁(使用SDK内置广告)<br/>• 1 - 自定义解锁(需监听解锁事件,自行处理)
UI控制
hideTopInfoboolfalse是否隐藏顶部信息区域
setTopOffsetint?null顶部信息偏移量(dp)
hideBottomInfoboolfalse是否隐藏底部信息区域
setBottomOffsetint?null底部信息偏移量(dp)
hideEnterboolfalse是否隐藏进入(下一集)按钮
hideLikeButtonboolfalse是否隐藏点赞按钮
hideFavorButtonboolfalse是否隐藏收藏按钮
showChangeBtnbooltrue是否显示"换一换"按钮
hideBackbooltrue是否隐藏返回按钮
播放配置
autoPlaybooltrue是否自动播放下一集
自定义广告
drawAdPositionsList<int>?nullDraw广告插入位置数组,如 [3, 6, 9] 表示在第3、6、9个位置插入
customDrawAdViewIdString?null自定义Draw广告视图ID
customBannerAdViewIdString?null自定义Banner广告视图ID

生命周期管理

DramaSwipeFlowNativeView 自动管理滑滑流生命周期:

  • 创建: Widget initState 时自动创建原生视图
  • 显示: Widget build 时自动显示
  • 销毁: Widget dispose 时自动销毁原生视图

手动销毁场景:如果需要在 Widget 存活期间销毁滑滑流,使用 DramaSwipeFlowController:

final controller = DramaSwipeFlowController();

// 手动销毁
await controller.dispose();

🧭 方式二:API 控制

适合需要精确控制滑滑流生命周期的场景,如原生 Activity/ViewController 中展示。

完整生命周期演示

import 'package:flutter/material.dart';
import 'package:pangrowth_content/pangrowth_content.dart';

class DramaSwipeFlowAPIDemo extends StatefulWidget {
  const DramaSwipeFlowAPIDemo({super.key});

  @override
  State<DramaSwipeFlowAPIDemo> createState() => _DramaSwipeFlowAPIDemoState();
}

class _DramaSwipeFlowAPIDemoState extends State<DramaSwipeFlowAPIDemo> {
  String? _widgetId;

  Future<void> _createAndShow() async {
    // 1. 创建滑滑流
    final config = DramaSwipeConfig(
      channelType: 1,
      dramaFree: 5,
      unlockEpisodesCount: 1,
      progressBarStyle: 1,
    );

    final result = await PangrowthContent.createDramaSwipeFlow(config: config);

    if (result['success'] == true) {
      _widgetId = result['widgetId'] as String;
      debugPrint('创建成功: $_widgetId');

      // 2. 显示滑滑流
      await PangrowthContent.showDramaSwipeFlow(_widgetId!);
      debugPrint('显示成功');
    }
  }

  Future<void> _hide() async {
    if (_widgetId != null) {
      await PangrowthContent.hideDramaSwipeFlow(_widgetId!);
      debugPrint('隐藏成功');
    }
  }

  Future<void> _destroy() async {
    if (_widgetId != null) {
      await PangrowthContent.destroyDramaSwipeFlow(_widgetId!);
      debugPrint('销毁成功');
      setState(() {
        _widgetId = null;
      });
    }
  }

  @override
  void dispose() {
    // 清理资源
    if (_widgetId != null) {
      PangrowthContent.destroyDramaSwipeFlow(_widgetId!);
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('API方式演示')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _widgetId == null ? _createAndShow : null,
              child: const Text('创建并显示'),
            ),
            ElevatedButton(
              onPressed: _widgetId != null ? _hide : null,
              child: const Text('隐藏'),
            ),
            ElevatedButton(
              onPressed: _widgetId != null ? _destroy : null,
              child: const Text('销毁'),
            ),
          ],
        ),
      ),
    );
  }
}

配置参数:DramaSwipeConfig

参数类型默认值说明
布局配置
bottomOffsetint?null底部偏移量(dp)
titleTopMarginint?null标题栏上边距(dp)
titleLeftMarginint?null标题栏左边距(dp)
titleRightMarginint?null标题栏右边距(dp)
界面控制
hideChannelNamebool?null是否隐藏频道名称
hideDramaInfobool?null是否隐藏底部短剧信息
hideDramaEnterbool?null是否隐藏底部短剧入口
hideClosebool?null是否隐藏关闭按钮
enableRefreshbool?null是否支持下拉刷新
hideLikeButtonbool?null是否隐藏点赞按钮
hideFavorButtonbool?null是否隐藏收藏按钮
hideDoubleClickLikebool?null是否禁止双击点赞
样式配置
progressBarStyleint?null播放器进度条样式:<br/>• 1 - 浅色进度条(适合深色背景)<br/>• 2 - 深色进度条(适合浅色背景)
customCategoryString?null自定义推荐频道名称
内容配置
dramaFreeint?null短剧免费集数
unlockEpisodesCountint?null每次解锁的集数(观看广告后解锁的集数)
topDramaIdint?null短剧置顶ID
频道配置
channelTypeint?null频道类型:<br/>• 1 - 仅推荐<br/>• 2 - 仅剧场<br/>• 3 - 推荐+剧场
contentTypeint?null仅Android支持<br/>内容类型:• 1 - 仅显示短剧内容<br/>iOS平台会忽略此参数

业务场景示例

新用户场景

final config = DramaSwipeConfig(
  hideChannelName: false,  // 显示频道名称,引导新用户
  hideDramaInfo: false,    // 显示详细信息
  enableRefresh: true,     // 支持下拉刷新
  progressBarStyle: 1,     // 浅色进度条
  dramaFree: 3,            // 新用户免费3集
  unlockEpisodesCount: 1,  // 每次解锁1集
  channelType: 1,          // 推荐频道
  customCategory: '新人推荐',
);

final result = await PangrowthContent.createDramaSwipeFlow(config: config);

VIP用户场景

final config = DramaSwipeConfig(
  hideChannelName: true,   // 简洁界面
  hideDramaInfo: false,    // 保留基础信息
  enableRefresh: true,
  progressBarStyle: 2,     // 深色进度条,更高端
  dramaFree: 999,          // VIP用户免费无限制
  unlockEpisodesCount: 1,
  channelType: 3,          // 推荐+剧场双频道
  customCategory: 'VIP专享',
  hideLikeButton: false,   // 保留社交功能
  hideFavorButton: false,
);

final result = await PangrowthContent.createDramaSwipeFlow(config: config);

简洁模式

final config = DramaSwipeConfig(
  hideChannelName: true,   // 隐藏频道名
  hideDramaInfo: true,     // 隐藏底部信息
  hideLikeButton: true,    // 隐藏点赞
  hideFavorButton: true,   // 隐藏收藏
  hideClose: false,        // 保留关闭按钮
  progressBarStyle: 1,
  dramaFree: 5,
  channelType: 1,
);

final result = await PangrowthContent.createDramaSwipeFlow(config: config);

🌍 平台差异

Android 专属参数

以下参数仅在 Android 平台生效,iOS 会安全忽略:

  • DramaSwipeConfig.contentType - 内容类型筛选

跨平台通用参数

以下参数在 Android 和 iOS 双端都支持:

  • 所有 hide* 系列参数(UI控制)
  • channelTypedramaFreeunlockEpisodesCount(业务配置)
  • progressBarStyle(样式配置)
  • enableRefreshautoPlay(交互配置)

💡 最佳实践

推荐使用 NativeView 方式

除非有特殊需求,否则推荐使用 DramaSwipeFlowNativeView,理由:

  • ✅ 自动管理生命周期,减少内存泄漏风险
  • ✅ 代码更简洁,符合 Flutter 开发习惯
  • ✅ 与 Flutter Widget 树完美集成
  • ✅ 支持 DramaSwipeFlowControllerDramaSwipeFlowListener

配置参数选择建议

  1. 只传递需要修改的参数:SDK 会为未传递的参数使用原生默认值
  2. 优先使用通用参数:避免使用平台专属参数,确保跨平台一致性
  3. 合理设置免费集数:
    • 新用户:2-3集(引导转化)
    • 普通用户:5集(标准体验)
    • VIP用户:999集(无限免费)

性能优化建议

  1. TabBar 场景必须暂停:切换 Tab 时使用 DramaSwipeFlowController.pause() 暂停播放
  2. 及时销毁:页面退出时确保调用 dispose()destroyDramaSwipeFlow()
  3. 避免频繁创建销毁:如需隐藏后再显示,使用 hide() 而非 destroy()

错误处理

// NativeView方式
DramaSwipeFlowNativeView(
  config: config,
  listener: DramaSwipeFlowListener(
    onSwipeFlowError: (error) {
      // 显示错误提示
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('加载失败: $error')),
      );
    },
  ),
)

// API方式
try {
  final result = await PangrowthContent.createDramaSwipeFlow(config: config);
  if (result['success'] != true) {
    debugPrint('创建失败');
  }
} catch (e) {
  debugPrint('异常: $e');
}

🔗 相关文档

需要进一步协助?

与 LightCore 技术顾问沟通,获取商业化策略与集成支持。