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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:09:25