Android应用实现列表点击切换YouTube Player视频
实现列表项点击更新YouTube播放器视频
背景
我正在开发首个Android应用,视图顶部为YouTube Player,下方展示第三方API返回的视频列表,需实现点击列表项时触发播放器加载对应视频。
问题
现有代码已成功添加顶部播放器和下方视频标题列表,但需将列表项设为可点击,通过API返回的youtubeId更新视频。现有代码如下:
fun VideoScreen( vm: VideoViewModel, videoId: String ) { LaunchedEffect(Unit, block = { vm.getVideoList() }) if (vm.errorMessage.isEmpty()) { Column { AndroidView(factory = { var view = YouTubePlayerView(it) val fragment = view.addYouTubePlayerListener( object : AbstractYouTubePlayerListener() { override fun onReady(youTubePlayer: YouTubePlayer) { super.onReady(youTubePlayer) youTubePlayer.loadVideo(videoId, 0f) } } ) view }) LazyColumn(modifier = Modifier.fillMaxHeight()) { items(vm.videoList) { video -> Column { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp), horizontalArrangement = Arrangement.SpaceBetween ) { Text( video.title, modifier = Modifier .fillMaxWidth(.9f) ) } Divider() } } } } } else { Text(vm.errorMessage) } }
API返回数据结构
[ { "title": "Homestead Fair 2022 — Friday Afternoon Music", "youtubeId": "9UOgiVIyv0A" }, { "title": "Homestead Fair 2022 — Friday Evening Music", "youtubeId": "yP84StSJre4" }, { "title": "\"Will He Find Faith on the Earth?\" When Economy Becomes Religion", "youtubeId": "Z_wlCnVpVYc" }, { "title": "Is Freedom Killing Our Liberty?", "youtubeId": "8sNJGLBB5sA" }, { "title": "The Roots of Industrialism and a Return to Sustainability", "youtubeId": "yyMZtfGziIc" }, { "title": "The Perils of \"Progress\" – Unveiling Modern Culture", "youtubeId": "XBZt8bv_tzU" } ]
已尝试方案
- 查阅android-youtube-player官方文档,未找到相关实现说明;
- 谷歌及Stack Overflow搜索仅找到XML代码或已废弃的旧实现。
解决方案
要实现点击列表项更新播放器视频,核心是保存YouTubePlayer实例并给列表项添加点击事件,具体修改步骤如下:
1. 保存YouTubePlayer实例
在VideoScreen函数内,用remember和mutableStateOf保存播放器实例,确保组件重组时不会丢失引用:
val youTubePlayer = remember { mutableStateOf<YouTubePlayer?>(null) }
2. 绑定播放器实例到状态
修改AndroidView中的onReady回调,将初始化好的播放器赋值给状态变量:
override fun onReady(player: YouTubePlayer) { super.onReady(player) this@VideoScreen.youTubePlayer.value = player // 保存实例 player.loadVideo(videoId, 0f) }
3. 给列表项添加点击事件
给列表项的Row添加clickable修饰符,点击时调用播放器的loadVideo方法加载对应视频:
Row( modifier = Modifier .fillMaxWidth() .padding(16.dp) .clickable { // 检查播放器是否已初始化,避免空指针 youTubePlayer.value?.loadVideo(video.youtubeId, 0f) }, horizontalArrangement = Arrangement.SpaceBetween )
修改后的完整代码
fun VideoScreen( vm: VideoViewModel, videoId: String ) { LaunchedEffect(Unit, block = { vm.getVideoList() }) // 保存YouTubePlayer实例 val youTubePlayer = remember { mutableStateOf<YouTubePlayer?>(null) } if (vm.errorMessage.isEmpty()) { Column { AndroidView(factory = { val view = YouTubePlayerView(it) view.addYouTubePlayerListener( object : AbstractYouTubePlayerListener() { override fun onReady(player: YouTubePlayer) { super.onReady(player) youTubePlayer.value = player player.loadVideo(videoId, 0f) } } ) view }) LazyColumn(modifier = Modifier.fillMaxHeight()) { items(vm.videoList) { video -> Column { Row( modifier = Modifier .fillMaxWidth() .padding(16.dp) .clickable { youTubePlayer.value?.loadVideo(video.youtubeId, 0f) }, horizontalArrangement = Arrangement.SpaceBetween ) { Text( video.title, modifier = Modifier.fillMaxWidth(.9f) ) } Divider() } } } } } else { Text(vm.errorMessage) } }
补充说明
- 点击列表项时先检查播放器实例是否为
null,避免播放器未初始化完成时触发空指针异常; - 如果需要优化体验,可以在播放器未就绪时禁用列表项点击,或者显示加载提示。
内容的提问来源于stack exchange,提问作者Circle B
相关产品推荐
相关产品推荐

