Android语言基础教程(189)Android多媒体应用播放音频与视频之使用VideoView播放视频:别让视频播放卡在起跑线!Android小哥手把手教你用VideoView“飙车”,附即抄即用

一、开篇唠嗑:谁还没被视频播放坑过?
还记得第一次在Android里搞视频播放的血泪史吗?对着MediaPlayer手写状态机,结果进度条比蜗牛还慢,声音画面玩起二人转…(此处应有捂脸表情)直到遇见VideoView——这个被官方塞进安卓工具箱的“懒人救星”,我才发现原来播视频可以像点奶茶一样简单!今天咱们就用打游戏刷副本的姿势,把它扒得底裤都不剩!

二、VideoView是何方神圣?
👉 官方人设:表面看是个能塞进布局的视频播放框,实际是MediaPlayer+SurfaceView的“私生子”!
👉 隐藏技能

  • 自动处理预加载、缓冲进度(再不用手写Loading圈)
  • 内置播放/暂停/进度拖拽三件套(省掉50行控制代码)
  • 支持MP4/3GP等主流格式(但遇到MKV请自觉转码)

重点来了:它本质上是个带着播放器灵魂的View!这意味着你既能当普通控件摆弄,又能直接调用start()、pause()等骚操作,堪称安卓界的“瑞士军刀”。

三、实战开始:从零搭建播放器(附可复制代码)

步骤1:在布局文件里挖个“视频坑”

<VideoView
    android:id="@+id/videoView"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:background="#000" />

⚠️ 注意:高度别写wrap_content!视频源尺寸参差不齐,容易引发布局坍塌惨案~

步骤2:在Activity里注入灵魂

class MainActivity : AppCompatActivity() {
    private lateinit var videoView: VideoView
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 绑定控件
        videoView = findViewById(R.id.videoView)
        
        // 设置视频路径(三种姿势任选)
        // 姿势1:播放本地文件
        val uri = Uri.parse("android.resource://${packageName}/${R.raw.demo}")
        // 姿势2:播放网络视频
        // val uri = Uri.parse("https://xxx.com/demo.mp4")
        // 姿势3:播放SD卡视频
        // val uri = Uri.fromFile(File("/sdcard/Movies/demo.mp4"))
        
        videoView.setVideoURI(uri)
        
        // 绑定媒体控制器(出现神秘控制条!)
        videoView.setMediaController(MediaController(this))
        
        // 设置准备完成监听(避免黑屏尴尬)
        videoView.setOnPreparedListener {
            videoView.start()
            Toast.makeText(this, "视频开始飙车啦!", Toast.LENGTH_SHORT).show()
        }
        
        // 设置播放完成回调
        videoView.setOnCompletionListener {
            Toast.makeText(this, "播完了,要不来个循环?", Toast.LENGTH_SHORT).show()
        }
    }
}

步骤3:别忘了在AndroidManifest.xml开权限!

<!-- 如果需要播放网络视频 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 如果需要读取SD卡 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

四、深度飙车技巧:让播放器更懂人心

场景1:实现“秒开播放”
在setOnPreparedListener里藏个黑科技:

videoView.setOnPreparedListener { mp ->
    mp.setOnBufferingUpdateListener { _, percent ->
        // 当缓冲超过30%立即播放,拒绝转圈等待
        if (percent > 30 && !videoView.isPlaying) {
            videoView.start()
        }
    }
}

场景2:应对生命周期暴击
在onPause()和onResume()里安排后事:

override fun onPause() {
    super.onPause()
    // 记录播放位置并暂停
    videoView.pause()
}

override fun onResume() {
    super.onResume()
    // 偷懒方案:直接续播(复杂场景建议用seekTo定位)
    videoView.start()
}

场景3:自定义控制条(高能玩法)
嫌弃系统控制条太丑?自己造个!

// 1. 隐藏系统控制器
videoView.setMediaController(null)

// 2. 在布局底部放自定义控制栏(包含播放/进度条/全屏按钮)
// 3. 手动绑定事件
btn_play.setOnClickListener {
    if(videoView.isPlaying) videoView.pause() else videoView.start()
}

seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
        if(fromUser) videoView.seekTo(progress * videoView.duration / 100)
    }
})

五、填坑指南:那些年我们踩过的雷

雷区1:网络视频加载慢
解决方案:

  • 用VideoView的setOnInfoListener监听MEDIA_INFO_BUFFERING_START/END
  • 缓冲时显示ProgressDialog,结束后隐藏

雷区2:切换横竖屏被重置
在AndroidManifest里给Activity加锁:

android:configChanges="orientation|screenSize"

雷区3:内存泄漏
记住三大纪律:

  • onDestroy中调用videoView.stopPlayback()
  • 移除所有监听器
  • 避免在RecyclerView的Item里直接使用VideoView(血的教训!)

六、扩展脑洞:VideoView还能这么玩

  • 实现小窗播放:用WindowManager把VideoView挂到桌面上
  • 视频轮播器:多个VideoView+ViewPager2打造抖音式体验
  • 蒙版特效:给VideoView覆盖半透明PNG实现异形播放框

七、结语
VideoView就像Android世界的乐高积木——看似简单但组合空间无限!从今天起别再复制粘贴老代码,用这些姿势解锁播放器新境界。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

值引力

持续创作,多谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值