👤 个人主页
个人主页提供用户信息展示、内容列表、关注关系等功能,适用于用户中心、个人资料页等场景。插件同时支持 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 平台上,可以通过 width
和 height
参数自定义个人主页的尺寸(单位:dp):
UserProfileNativeView(
config: const UserProfileConfig(
pageType: UserProfilePageType.userHomePage,
scene: 'user_center',
width: 360, // 宽度 360dp
height: 640, // 高度 640dp
),
)
注意: 不设置
width
和height
时,默认使用match_parent
填充父容器。iOS 平台不支持这两个参数。
生命周期与限制
- 单实例约束:插件内部限制同一时刻仅允许存在一个个人主页实例,创建新的
UserProfileNativeView
前需确保旧实例已被销毁。 - 平台视图限制:PlatformView 由原生渲染,避免在其上方叠加
Positioned
/Stack
等复杂布局,必要时可在外层使用安全区域、背景容器。 - 销毁策略:
UserProfileNativeView
在dispose
阶段会自动调用PangrowthContent.destroyUserProfile
,如果在外层缓存了profileId
,可在自定义流程中重复调用(幂等)。
🧭 方式二:使用 API 控制个人主页
API 方式用于历史项目兼容或需要原生容器承载的场景。如无特殊需求,仍建议优先选择 NativeView 方案。
调用流程
createUserProfile(config)
创建个人主页,获得profileId
;showUserProfile(profileId)
打开原生个人主页页面(Android 启动 Activity,iOS 推入控制器);- 页面结束时调用
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 默认值。
通用配置
参数 | 类型 | 平台支持 | 说明 | 默认值 |
---|---|---|---|---|
pageType | UserProfilePageType? | ✅ 双端 | 页面类型:<br/>- UserProfilePageType.userHomePage : 个人主页<br/>- UserProfilePageType.userFavoriteVideoPage : 喜欢的视频页<br/>- UserProfilePageType.userFocusPage : 关注页 | null(SDK默认为个人主页) |
hideCloseIcon | bool? | ✅ 双端 | 是否隐藏关闭按钮 | null(使用SDK默认) |
scene | String? | ✅ 双端 | 场景标识,用于内容定制业务,建议传入有业务含义的标识如 'user_center' 、'profile_favorites' 等 | null |
extra | Map<String, dynamic>? | ✅ 双端 | 自定义扩展字段,将在事件回调中透传 | null |
Android专用配置
参数 | 类型 | 说明 | 默认值 |
---|---|---|---|
width | int? | 组件宽度,单位 dp | null(使用match_parent) |
height | int? | 组件高度,单位 dp | null(使用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:个人主页无法创建或显示空白
可能原因:
- 未完成插件初始化,确保调用了
PangrowthContent.start()
- 穿山甲SDK配置不正确,检查
appId
和appName
是否正确 - 未正确配置个人主页的 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)),
],
)
🌍 平台差异与适配建议
特性 | Android | iOS | 说明 |
---|---|---|---|
个人主页 | ✅ 完整支持 | ✅ 完整支持 | 双端均支持 LCDAccessUserCenterViewController |
喜欢的视频页 | ✅ 完整支持 | ✅ 完整支持 | 双端均支持 LCDAccessUserLikeListViewController |
关注页 | ✅ 完整支持 | ✅ 完整支持 | 双端均支持 LCDAccessUserFollowListViewController |
NativeView组件 | ✅ 可用 | ✅ 可用 | 双端均通过 PlatformView 方式实现 |
API方式 | ✅ 可用 | ✅ 可用 | 双端均支持 create/show/destroy API |
自定义尺寸(width /height ) | ✅ 支持 | ✅ 支持 | 双端均支持通过 width 和 height 设置尺寸 |
容器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专用
);
}
📚 参考文档
- 沉浸式小视频 - 全屏沉浸式视频播放
- 宫格与双Feed小视频 - 宫格视频组件
- 事件处理 - 完整的事件监听机制
- Widget组件总览 - 所有组件导航