📹 小视频模块
版本 PanGrowth

👤 个人主页

个人主页提供用户信息展示、内容列表、关注关系等功能,适用于用户中心、个人资料页等场景。插件同时支持 NativeView 组件API 控制 两种接入方式。

平台支持:

  • Android: 完整支持个人主页、喜欢的视频页、关注页
  • iOS: 完整支持个人主页、喜欢的视频页、关注页

🚪 接入方式概览

方式推荐场景实现特点
UserProfileNativeView 组件(推荐)Flutter 页面内嵌个人主页,追求最快集成自动管理创建/销毁,Flutter 布局友好
API 调用需要在原生容器中展示,或兼容历史流程主动控制生命周期

两种方式共用 UserProfileConfig 配置对象,事件回调也通过同一套监听体系。

✅ 方式一:使用 UserProfileNativeView(推荐)

UserProfileNativeView 通过 PlatformView 内嵌原生个人主页视图,Flutter 端仅需像普通 Widget 一样使用。

基础用法

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('个人主页')),
      body: UserProfileNativeView(
        config: const UserProfileConfig(
          pageType: UserProfilePageType.userHomePage,  // 个人主页
          scene: 'user_center',                         // 场景标识
          hideCloseIcon: false,                         // 显示关闭按钮
        ),
      ),
    );
  }
}

三种页面类型

UserProfilePageType 枚举定义了三种页面类型:

1. 个人主页(userHomePage)

展示用户基本信息、发布的视频列表等:

UserProfileNativeView(
  config: const UserProfileConfig(
    pageType: UserProfilePageType.userHomePage,
    scene: 'profile_main',
  ),
)

2. 喜欢的视频页(userFavoriteVideoPage)

展示用户点赞/收藏的视频列表:

UserProfileNativeView(
  config: const UserProfileConfig(
    pageType: UserProfilePageType.userFavoriteVideoPage,
    scene: 'profile_favorites',
  ),
)

3. 关注页(userFocusPage)

展示用户关注的其他用户列表:

UserProfileNativeView(
  config: const UserProfileConfig(
    pageType: UserProfilePageType.userFocusPage,
    scene: 'profile_following',
  ),
)

使用控制器进行外部控制

通过 UserProfileController 可以在外部控制个人主页的刷新、返回键等行为:

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

  @override
  State<UserProfileWithControllerPage> createState() => _UserProfileWithControllerPageState();
}

class _UserProfileWithControllerPageState extends State<UserProfileWithControllerPage> {
  late final UserProfileController _controller;

  @override
  void initState() {
    super.initState();
    _controller = UserProfileController();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('个人主页'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () => _controller.refresh(),
          ),
        ],
      ),
      body: UserProfileNativeView(
        config: const UserProfileConfig(
          pageType: UserProfilePageType.userHomePage,
          scene: 'user_center',
        ),
        controller: _controller,
      ),
    );
  }
}

UserProfileController 方法

方法平台支持说明使用场景
refresh()🤖 Android刷新个人主页数据用户下拉刷新或点击刷新按钮
backRefresh()🤖 Android返回场景时的挽留刷新从详情页返回个人主页时自动刷新
canBackPress()✅ 双端校验返回键是否可直接关闭Android返回键拦截
dispose()✅ 双端销毁个人主页实例Widget销毁时调用

注意: refresh()backRefresh() 方法仅在 Android 平台有效。iOS 平台调用这些方法会返回成功但不执行任何操作(为保持API一致性)。

监听个人主页事件

可通过 UserProfileListener 获取组件创建、销毁及错误事件,便于埋点或自定义 UI:

UserProfileNativeView(
  config: const UserProfileConfig(
    pageType: UserProfilePageType.userHomePage,
    scene: 'user_center',
  ),
  listener: UserProfileListener(
    onProfileReady: (profileId) {
      debugPrint('个人主页就绪: $profileId');
    },
    onProfileDisposed: () {
      debugPrint('个人主页已释放');
    },
    onProfileError: (error) {
      debugPrint('个人主页加载失败: $error');
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('个人主页加载失败,请稍后重试')),
      );
    },
  ),
)

自定义尺寸(Android专用)

在 Android 平台上,可以通过 widthheight 参数自定义个人主页的尺寸(单位:dp):

UserProfileNativeView(
  config: const UserProfileConfig(
    pageType: UserProfilePageType.userHomePage,
    scene: 'user_center',
    width: 360,   // 宽度 360dp
    height: 640,  // 高度 640dp
  ),
)

注意: 不设置 widthheight 时,默认使用 match_parent 填充父容器。iOS 平台不支持这两个参数。

生命周期与限制

  • 单实例约束:插件内部限制同一时刻仅允许存在一个个人主页实例,创建新的 UserProfileNativeView 前需确保旧实例已被销毁。
  • 平台视图限制:PlatformView 由原生渲染,避免在其上方叠加 Positioned/Stack 等复杂布局,必要时可在外层使用安全区域、背景容器。
  • 销毁策略:UserProfileNativeViewdispose 阶段会自动调用 PangrowthContent.destroyUserProfile,如果在外层缓存了 profileId,可在自定义流程中重复调用(幂等)。

🧭 方式二:使用 API 控制个人主页

API 方式用于历史项目兼容或需要原生容器承载的场景。如无特殊需求,仍建议优先选择 NativeView 方案。

调用流程

  1. createUserProfile(config) 创建个人主页,获得 profileId;
  2. showUserProfile(profileId) 打开原生个人主页页面(Android 启动 Activity,iOS 推入控制器);
  3. 页面结束时调用 destroyUserProfile(profileId) 释放资源。

参考实现

class UserProfileLauncher {
  String? _profileId;

  Future<void> openUserProfile({
    UserProfilePageType pageType = UserProfilePageType.userHomePage,
  }) async {
    final result = await PangrowthContent.createUserProfile(
      UserProfileConfig(
        pageType: pageType,
        scene: 'user_center',
        hideCloseIcon: false,
      ),
    );

    if (result['success'] != true) {
      debugPrint('创建个人主页失败: $result');
      return;
    }

    _profileId = result['profileId'] as String;

    // Android: 可指定容器ID
    // iOS: 可指定展示样式
    await PangrowthContent.showUserProfile(
      _profileId!,
      containerId: null,  // Android专用,默认使用android.R.id.content
      presentationStyle: Platform.isIOS ? 'pageSheet' : null,  // iOS专用
    );
  }

  Future<void> dispose() async {
    if (_profileId != null) {
      await PangrowthContent.destroyUserProfile(_profileId!);
      _profileId = null;
    }
  }
}

使用示例:打开不同类型的个人主页

// 打开个人主页
await launcher.openUserProfile(
  pageType: UserProfilePageType.userHomePage,
);

// 打开喜欢的视频页
await launcher.openUserProfile(
  pageType: UserProfilePageType.userFavoriteVideoPage,
);

// 打开关注页
await launcher.openUserProfile(
  pageType: UserProfilePageType.userFocusPage,
);

destroyUserProfile 为幂等调用,即使个人主页已关闭再次调用也不会抛出异常。

🧩 公共配置项(UserProfileConfig)

以下参数两种接入方式均可使用,未显式赋值时会使用 SDK 默认值。

通用配置

参数类型平台支持说明默认值
pageTypeUserProfilePageType?✅ 双端页面类型:<br/>- UserProfilePageType.userHomePage: 个人主页<br/>- UserProfilePageType.userFavoriteVideoPage: 喜欢的视频页<br/>- UserProfilePageType.userFocusPage: 关注页null(SDK默认为个人主页)
hideCloseIconbool?✅ 双端是否隐藏关闭按钮null(使用SDK默认)
sceneString?✅ 双端场景标识,用于内容定制业务,建议传入有业务含义的标识如 'user_center''profile_favorites'null
extraMap<String, dynamic>?✅ 双端自定义扩展字段,将在事件回调中透传null

Android专用配置

参数类型说明默认值
widthint?组件宽度,单位 dpnull(使用match_parent)
heightint?组件高度,单位 dpnull(使用match_parent)

📡 事件监听

通过 UserProfileListener 获取创建、销毁、错误回调。

常见个人主页事件如下:

UserProfileEventType触发时机常用字段
profileReady个人主页创建完成profileId
follow用户点击关注按钮userId(被关注用户ID)
unfollow用户取消关注userId
avatarClick点击头像userId
videoClick点击视频videoId
pageShow个人主页对用户可见contentId(profileId)
pageHide个人主页离开前台contentId
destroyed原生页面销毁contentId

💡 使用场景与实践

场景1:用户中心

在用户中心展示个人主页,用户可以查看自己的信息和发布的视频:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('个人中心')),
      body: UserProfileNativeView(
        config: const UserProfileConfig(
          pageType: UserProfilePageType.userHomePage,
          scene: 'user_center',
          hideCloseIcon: true,  // 用户中心不显示关闭按钮
        ),
      ),
    );
  }
}

场景2:TabBar中的多个个人主页标签

在 TabBar 中展示个人主页的不同部分(主页、喜欢、关注):

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

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('我的主页'),
          bottom: const TabBar(
            tabs: [
              Tab(text: '主页'),
              Tab(text: '喜欢'),
              Tab(text: '关注'),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            UserProfileNativeView(
              config: const UserProfileConfig(
                pageType: UserProfilePageType.userHomePage,
                scene: 'tab_profile',
              ),
            ),
            UserProfileNativeView(
              config: const UserProfileConfig(
                pageType: UserProfilePageType.userFavoriteVideoPage,
                scene: 'tab_favorites',
              ),
            ),
            UserProfileNativeView(
              config: const UserProfileConfig(
                pageType: UserProfilePageType.userFocusPage,
                scene: 'tab_following',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

场景3:查看其他用户的个人主页

通过 extra 参数传递用户ID,查看其他用户的个人主页:

class OtherUserProfilePage extends StatelessWidget {
  final String userId;

  const OtherUserProfilePage({
    super.key,
    required this.userId,
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('用户主页')),
      body: UserProfileNativeView(
        config: UserProfileConfig(
          pageType: UserProfilePageType.userHomePage,
          scene: 'other_user_profile',
          extra: {
            'userId': userId,  // 传递用户ID
          },
        ),
      ),
    );
  }
}

场景4:Android端自定义尺寸的个人主页卡片

在 Android 平台上,将个人主页作为卡片嵌入到其他页面中:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('用户推荐')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          const Text('推荐用户', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          const SizedBox(height: 16),
          SizedBox(
            height: 400,  // 外层容器高度
            child: UserProfileNativeView(
              config: const UserProfileConfig(
                pageType: UserProfilePageType.userHomePage,
                scene: 'recommend_card',
                width: 360,   // Android: 卡片宽度
                height: 400,  // Android: 卡片高度
                hideCloseIcon: true,
              ),
            ),
          ),
          const SizedBox(height: 16),
          const Text('更多推荐内容...'),
        ],
      ),
    );
  }
}

🛠️ 故障排查

问题1:个人主页无法创建或显示空白

可能原因:

  1. 未完成插件初始化,确保调用了 PangrowthContent.start()
  2. 穿山甲SDK配置不正确,检查 appIdappName 是否正确
  3. 未正确配置个人主页的 config 参数

解决方法:

// 1. 确保在使用个人主页前完成初始化
await PangrowthContent.start(
  startDrama: true,  // 或 startStory: true
);

// 2. 验证配置是否正确
UserProfileNativeView(
  config: const UserProfileConfig(
    pageType: UserProfilePageType.userHomePage,
    scene: 'user_center',  // 必须提供场景标识
  ),
);

// 3. 监听错误事件
UserProfileListener(
  onProfileError: (error) {
    debugPrint('个人主页错误: $error');
  },
)

问题2:个人主页内存泄漏

原因:未正确销毁个人主页实例

解决方法:

@override
void dispose() {
  // 方式1: NativeView会自动销毁,但如果使用了Controller需要手动释放
  _controller.dispose();

  // 方式2: API方式必须手动销毁
  if (_profileId != null) {
    PangrowthContent.destroyUserProfile(_profileId!);
  }

  super.dispose();
}

问题3:个人主页创建成功但showUserProfile失败

原因:Android端可能是容器ID配置问题,iOS端可能是展示样式不支持

解决方法:

// Android: 使用默认容器ID
await PangrowthContent.showUserProfile(profileId, containerId: null);

// iOS: 使用支持的展示样式
await PangrowthContent.showUserProfile(
  profileId,
  presentationStyle: 'pageSheet',  // 或 'fullScreen', 'formSheet'
);

问题4:TabBar切换时个人主页显示异常

原因:在TabBarView中使用多个UserProfileNativeView可能导致实例冲突

解决方法:

// 方式1: 使用AutomaticKeepAliveClientMixin保持状态
class UserProfileTab extends StatefulWidget {
  final UserProfilePageType pageType;
  const UserProfileTab({super.key, required this.pageType});

  @override
  State<UserProfileTab> createState() => _UserProfileTabState();
}

class _UserProfileTabState extends State<UserProfileTab> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);  // 必须调用
    return UserProfileNativeView(
      config: UserProfileConfig(
        pageType: widget.pageType,
        scene: 'tab_${widget.pageType.name}',
      ),
    );
  }
}

// 方式2: 使用IndexedStack替代TabBarView
body: IndexedStack(
  index: _currentIndex,
  children: [
    UserProfileNativeView(config: const UserProfileConfig(pageType: UserProfilePageType.userHomePage)),
    UserProfileNativeView(config: const UserProfileConfig(pageType: UserProfilePageType.userFavoriteVideoPage)),
    UserProfileNativeView(config: const UserProfileConfig(pageType: UserProfilePageType.userFocusPage)),
  ],
)

🌍 平台差异与适配建议

特性AndroidiOS说明
个人主页✅ 完整支持✅ 完整支持双端均支持 LCDAccessUserCenterViewController
喜欢的视频页✅ 完整支持✅ 完整支持双端均支持 LCDAccessUserLikeListViewController
关注页✅ 完整支持✅ 完整支持双端均支持 LCDAccessUserFollowListViewController
NativeView组件✅ 可用✅ 可用双端均通过 PlatformView 方式实现
API方式✅ 可用✅ 可用双端均支持 create/show/destroy API
自定义尺寸(width/height)✅ 支持✅ 支持双端均支持通过 widthheight 设置尺寸
容器ID(containerId)✅ 支持-仅Android使用,iOS无此参数
展示样式(presentationStyle)-✅ 支持仅iOS使用,Android无此参数

跨平台适配建议

双端均支持个人主页功能,可直接使用统一代码:

Widget buildUserProfile() {
  // 双端统一使用 UserProfileNativeView
  return UserProfileNativeView(
    config: const UserProfileConfig(
      pageType: UserProfilePageType.userHomePage,
      scene: 'user_center',
    ),
  );
}

如需使用平台特定参数,可使用条件判断:

Widget buildUserProfile() {
  return UserProfileNativeView(
    config: UserProfileConfig(
      pageType: UserProfilePageType.userHomePage,
      scene: 'user_center',
      // Android专用参数(iOS会忽略)
      width: Platform.isAndroid ? 360 : null,
      height: Platform.isAndroid ? 640 : null,
    ),
  );
}

// 或在API方式中处理iOS专用参数
Future<void> showProfile(String profileId) async {
  await PangrowthContent.showUserProfile(
    profileId,
    containerId: Platform.isAndroid ? customContainerId : null,  // Android专用
    presentationStyle: Platform.isIOS ? 'pageSheet' : null,      // iOS专用
  );
}

📚 参考文档


需要进一步协助?

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