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

Android Studio中如何实现视频自动裁剪适配竖屏VideoView?

Android竖屏VideoView自动中心裁剪视频实现方案

原生VideoView默认使用FIT_CENTER适配逻辑,会出现留黑边、无法自动裁剪超出内容的问题,以下两种方案都可以直接实现目标效果:横屏视频自动裁去左右两侧内容居中显示、竖屏视频适配时裁去上下超出部分,所有超出控件范围的内容都会被隐藏,和短视频信息流的视频显示效果一致。


方案一:自定义中心裁剪VideoView(无额外依赖,轻量)

不需要引入第三方库,直接继承原生VideoView重写测量逻辑,实现和ImageView.CENTER_CROP一致的适配效果,加载Firebase视频的逻辑和原生用法完全兼容。

  1. 新建CenterCropVideoView类,复制以下代码:
public class CenterCropVideoView extends VideoView {
    public CenterCropVideoView(Context context) {
        super(context);
    }

    public CenterCropVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CenterCropVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int viewWidth = MeasureSpec.getSize(widthMeasureSpec);
        int viewHeight = MeasureSpec.getSize(heightMeasureSpec);
        int videoWidth = getVideoWidth();
        int videoHeight = getVideoHeight();

        // 视频未加载完成时走默认测量逻辑
        if (videoWidth == 0 || videoHeight == 0) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }

        float viewAspectRatio = (float) viewWidth / viewHeight;
        float videoAspectRatio = (float) videoWidth / videoHeight;
        int calcWidth, calcHeight;

        // 横屏视频(宽高比大于控件):按控件高度铺满,裁剪左右多余部分
        if (videoAspectRatio > viewAspectRatio) {
            calcHeight = viewHeight;
            calcWidth = (int) (viewHeight * videoAspectRatio);
        } 
        // 竖屏视频(宽高比小于控件):按控件宽度铺满,裁剪上下多余部分
        else {
            calcWidth = viewWidth;
            calcHeight = (int) (viewWidth / videoAspectRatio);
        }
        setMeasuredDimension(calcWidth, calcHeight);
    }
}
  1. 布局文件中替换原生VideoView为自定义控件,按需求设置竖屏尺寸即可:
<com.your.package.CenterCropVideoView
    android:id="@+id/cropVideoView"
    android:layout_width="match_parent"
    android:layout_height="400dp"
    android:layout_centerHorizontal="true"/>
  1. 视频加载时增加适配兜底,避免部分机型首次加载获取视频宽高失败:
CenterCropVideoView videoView = findViewById(R.id.cropVideoView);
videoView.setVideoURI(Uri.parse("你的Firebase视频地址"));
// 视频准备完成后重新触发布局测量,保证裁剪逻辑生效
videoView.setOnPreparedListener(mediaPlayer -> {
    videoView.requestLayout();
    videoView.start();
});

方案二:使用AndroidX Media3 ExoPlayer实现(推荐长期迭代场景)

如果后续需要扩展视频缓存、倍速播放、清晰度切换等能力,可以直接用官方维护的Media3播放器,自带中心裁剪配置,不需要自定义控件。

  1. 先在模块级build.gradle引入依赖:
implementation "androidx.media3:media3-exoplayer:1.2.1"
implementation "androidx.media3:media3-ui:1.2.1"
  1. 布局中添加PlayerView,通过resize_mode直接开启中心裁剪效果:
<androidx.media3.ui.PlayerView
    android:id="@+id/playerView"
    android:layout_width="match_parent"
    android:layout_height="400dp"
    app:resize_mode="zoom"
    app:use_controller="false"
    android:layout_centerHorizontal="true"/>
  1. 初始化播放器加载Firebase视频即可,zoom模式会自动完成居中裁剪,超出控件的内容自动隐藏:
PlayerView playerView = findViewById(R.id.playerView);
ExoPlayer player = new ExoPlayer.Builder(this).build();
playerView.setPlayer(player);
MediaItem mediaItem = MediaItem.fromUri(Uri.parse("你的Firebase视频地址"));
player.setMediaItem(mediaItem);
player.prepare();
player.play();

注意事项

  • 两种方案都是显示层的裁剪调整,不会修改原视频文件,不需要提前对Firebase上存储的视频做转码、裁剪预处理。
  • 裁剪逻辑默认居中对齐,横屏视频会自动保留中间核心画面、裁掉左右两侧超出部分,完全匹配需求。
  • 使用自定义VideoView方案时,父布局请保持默认android:clipChildren="true"配置,否则超出控件范围的视频内容无法被裁剪隐藏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:39:40