You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Dummy Data中在ViewHolder加载YouTube视频URL?

在RecyclerView的ViewHolder中加载并播放YouTube视频

可行性说明

完全可行,但Android原生VideoView无法直接播放YouTube链接,需要借助YouTube Android Player API或支持解析YouTube流的第三方播放器库,这里推荐使用官方API,适配性更有保障。

实现步骤

1. 集成YouTube Android Player API

在Module级别的build.gradle中添加依赖:

dependencies {
    implementation 'com.google.android.youtube:youtube-android-player:10.0.1'
}

2. 修改Item布局

在RecyclerView的Item布局文件中,添加YouTubePlayerView作为视频播放容器:

<com.google.android.youtube.player.YouTubePlayerView
    android:id="@+id/youtube_player"
    android:layout_width="match_parent"
    android:layout_height="200dp" />

3. 改造ViewHolder实现视频加载

处理播放器初始化、视频ID提取,同时适配RecyclerView的复用逻辑:

class MusicViewHolder(private val binding: YourItemBinding) : RecyclerView.ViewHolder(binding.root), YouTubePlayer.OnInitializedListener {
    private var currentVideoId: String? = null
    private var youtubePlayer: YouTubePlayer? = null

    // 从YouTube链接中提取视频ID
    private fun extractVideoId(youtubeUrl: String): String? {
        val pattern = "(?<=watch\\?v=|/videos/|embed/|youtu.be/|/v/|/e/|watch\\?v%3D|watch\\?feature=player_embedded&v=|%2Fvideos%2F|embed%2F|youtu.be%2F|%2Fv%2F)[^#&?\\n]*"
        return Regex(pattern).find(youtubeUrl)?.value
    }

    fun bind(music: Music?) {
        music?.apply {
            binding.ivImg.load(this.imgUrl) {
                crossfade(true)
            }
            binding.tvTitle.text = this.title
            binding.tvDesc.text = this.desc

            currentVideoId = extractVideoId(videoUrl)
            // 初始化播放器,替换为你的YouTube API密钥
            binding.youtubePlayer.initialize("YOUR_YOUTUBE_API_KEY", this@MusicViewHolder)
        }
    }

    override fun onInitializationSuccess(provider: YouTubePlayer.Provider?, player: YouTubePlayer?, wasRestored: Boolean) {
        youtubePlayer = player
        player?.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT)
        currentVideoId?.let { videoId ->
            if (!wasRestored) {
                player.loadVideo(videoId) // 加载并自动播放;用cueVideo可只加载不播放
            }
        }
    }

    override fun onInitializationFailure(provider: YouTubePlayer.Provider?, errorReason: YouTubeInitializationResult?) {
        errorReason?.let {
            if (it.isUserRecoverableError) {
                it.getErrorDialog(itemView.context, 1).show()
            } else {
                Toast.makeText(itemView.context, "视频播放器初始化失败", Toast.LENGTH_SHORT).show()
            }
        }
    }

    // 滚动时暂停不可见项的视频
    fun onViewDetachedFromWindow() {
        youtubePlayer?.pause()
    }

    // 回收ViewHolder时释放播放器资源
    fun releasePlayer() {
        youtubePlayer?.release()
    }
}

4. 适配RecyclerView的复用逻辑

在Adapter中重写相关方法,避免资源泄漏和无效播放:

class MusicAdapter(private val musicList: List<Music>) : RecyclerView.Adapter<MusicViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MusicViewHolder {
        val binding = YourItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return MusicViewHolder(binding)
    }

    override fun onBindViewHolder(holder: MusicViewHolder, position: Int) {
        holder.bind(musicList[position])
    }

    override fun onViewDetachedFromWindow(holder: MusicViewHolder) {
        super.onViewDetachedFromWindow(holder)
        holder.onViewDetachedFromWindow()
    }

    override fun onViewRecycled(holder: MusicViewHolder) {
        super.onViewRecycled(holder)
        holder.releasePlayer()
    }

    override fun getItemCount(): Int = musicList.size
}

注意事项

  • API密钥:需在Google Cloud控制台创建并启用YouTube Data API v3的密钥,否则播放器无法初始化。
  • 性能优化:滚动时暂停不可见视频,避免占用过多系统资源。
  • 权限:确保App已申请INTERNET权限,用于加载在线视频。
  • 替代方案:若不愿使用官方API,可尝试ExoPlayer配合视频流解析库,但该方式可能违反YouTube服务条款,需谨慎使用。

内容的提问来源于stack exchange,提问作者ryhanhxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:23:10