如何在match_parent的TextureView上实现视频居中裁剪循环播放
嘿,我来帮你搞定这个TextureView循环播放背景视频且居中裁剪的需求!
实现TextureView循环播放背景视频(居中裁剪+Match Parent)
1. 补全居中裁剪的缩放计算函数
你已经写了updateTextureViewSize的开头,我来帮你补全这个函数,实现和ImageView的CENTER_CROP一模一样的效果——让视频按比例缩放填满整个TextureView,超出的部分自动裁剪,同时保证视频稳稳居中:
private void updateTextureViewSize(int viewWidth, int viewHeight) { float scaleX = 1.0f; float scaleY = 1.0f; // 先确保已经拿到视频的真实宽高 if (mVideoWidth <= 0 || mVideoHeight <= 0) { return; } // 计算视频和TextureView的宽高比例 float videoRatio = (float) mVideoWidth / mVideoHeight; float viewRatio = (float) viewWidth / viewHeight; // 对比两个比例,决定缩放方向: // 如果视频更宽,就按View的高度来缩放,宽度超出的部分裁剪 if (videoRatio > viewRatio) { scaleX = (float) mVideoWidth / viewWidth; scaleY = scaleX; } else { // 如果视频更高,就按View的宽度来缩放,高度超出的部分裁剪 scaleY = (float) mVideoHeight / viewHeight; scaleX = scaleY; } // 计算偏移量,让缩放后的视频在View里居中显示 float scaledWidth = mVideoWidth / scaleX; float scaledHeight = mVideoHeight / scaleY; float dx = (viewWidth - scaledWidth) / 2; float dy = (viewHeight - scaledHeight) / 2; // 把变换规则应用到TextureView上 Matrix matrix = new Matrix(); matrix.setScale(scaleX, scaleY); matrix.postTranslate(dx, dy); mTextureView.setTransform(matrix); }
这个函数的逻辑很清晰:先选对缩放比例保证视频填满View,再算偏移让视频居中,最后用Matrix把变换生效。
2. 找准调用缩放函数的时机
这个函数不能瞎调用,得在几个关键节点触发:
- 视频加载完成,拿到真实宽高之后
- TextureView的尺寸变化时(比如屏幕旋转、窗口大小调整)
给TextureView加个布局变化监听,自动触发缩放:
mTextureView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { int viewWidth = right - left; int viewHeight = bottom - top; updateTextureViewSize(viewWidth, viewHeight); } });
另外,用MediaPlayer加载视频的时候,在准备完成的回调里拿视频宽高并调用缩放:
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mVideoWidth = mp.getVideoWidth(); mVideoHeight = mp.getVideoHeight(); // 触发缩放调整 updateTextureViewSize(mTextureView.getWidth(), mTextureView.getHeight()); // 开始播放 mp.start(); // 直接设置循环播放 mp.setLooping(true); } });
3. 循环播放的小技巧
其实超级简单,给MediaPlayer加一句mp.setLooping(true)就搞定了,上面的代码已经包含了。如果是用ExoPlayer的话,就设置player.setRepeatMode(REPEAT_MODE_ALL),效果一样。
4. 布局基础设置
别忘了在XML里把TextureView设成match_parent,确保它占满整个容器:
<TextureView android:id="@+id/texture_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/black" />
几个小提醒
- 一定要处理好
MediaPlayer的生命周期,在Activity/Fragment销毁的时候记得调用mp.release(),不然会内存泄漏哦 - 如果视频加载慢,可以给TextureView先设一张占位图,提升用户体验
内容的提问来源于stack exchange,提问作者Chandan Pednekar
相关产品推荐
相关产品推荐

