我用的播放器是KMedia,一个开源的播放器,链接如下

https://github.com/BlackQi/KMedia

我个人觉得还是很好用的,支持定制。现在遇到一个问题就是播放时横屏铺满全屏视频被拉伸的问题(我们的视频比例为16:9 也就是1.778:1)。由于该播放器没有提供屏幕比例调整的api,所以就只能自己搞了。

思路,原本是想直接一刀切:横屏时把window的尺寸调整一下,那window所包含的内容不就直接改了吗 也不用过多的调整UI,而且好用的一点是window调整之后会以屏幕居中,就不用手动调整窗口的位置了。

需要注意的是 如果有虚拟按键的情况,以上链接获取的尺寸是不准确的,可以这样搞

Display display = getWindowManager().getDefaultDisplay();
int width;
int height;
Point outPoint = new Point();
if (Build.VERSION.SDK_INT >= 19) {
    // 可能有虚拟按键的情况
    display.getRealSize(outPoint);
 } else {
            // 不可能有虚拟按键
    display.getSize(outPoint);
 }
 //获取屏幕真实宽度跟高度
 width = outPoint.x;
 height = outPoint.y;

然后在横竖屏切换的函数onConfigurationChanged()中调用以下函数

private void setLayoutParmas(boolean isHor) {        
        if (isHor){
            //把window调整宽高比为16:9
            Window window = getWindow();
            WindowManager.LayoutParams windowLayoutParams = window.getAttributes();
            windowLayoutParams.width = (int) (height * 1.778);
            windowLayoutParams.height = height;
            window.setAttributes(windowLayoutParams);
            //横屏时屏幕比例调整为16:9
            playerViewParent.setLayoutParams(new LinearLayout.LayoutParams(width, height));
            playerView.getSurfaceView().setLayoutParams(new FrameLayout.LayoutParams((int) (height * 1.778), height));

        } else {
            //把window调成宽高比为正常尺寸
            Window window = getWindow();
            WindowManager.LayoutParams windowLayoutParams = window.getAttributes();
            windowLayoutParams.width = width;
            windowLayoutParams.height = height;
            window.setAttributes(windowLayoutParams);
            //竖屏时屏幕比例调整为16:9
            playerViewParent.setLayoutParams(new LinearLayout.LayoutParams(width, (int) (width * (0.563))));
            playerView.getSurfaceView().setLayoutParams(new FrameLayout.LayoutParams(width, (int) (width * (0.563))));
        }
}

但是这样做发现了一个问题,window的尺寸是能正常调整了,但是横屏状态下怎么也隐藏不了状态栏,我之前状态栏都是正常的,竖屏显示,横屏隐藏,只加了这些代码,为什么就不正常了?

先说结论:window非全屏时是不能正常操作状态栏的,具体参考

我没有看有没有其他的方法能修改状态栏,时间有限,直接改view的尺寸吧,方法调整为

/**
     * 动态设置播放器高度
     * @param isHor 是否是横屏
     */
    private void setLayoutParmas(boolean isHor) {
        Display display = getWindowManager().getDefaultDisplay();
        int width;
        int height;
        Point outPoint = new Point();
        if (Build.VERSION.SDK_INT >= 19) {
            // 可能有虚拟按键的情况
            display.getRealSize(outPoint);
        } else {
            // 不可能有虚拟按键
            display.getSize(outPoint);
        }
        //获取屏幕真实宽度跟高度
        width = outPoint.x;
        height = outPoint.y;

        if (isHor){
            //视频窗口父布局 全屏
            playerViewParent.setLayoutParams(new LinearLayout.LayoutParams(width, height));
            
            if (width/height >= 1.97f ){
                //全面屏
                //视频窗口宽度为高度的1.778倍(16:9)
                FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams((int) (height * 1.778), height);
                //窗口居中 设置宽度后 视频窗口默认在左侧 调整左间距 公式 (屏幕整体宽度-视频窗口宽度 - 状态栏高度 - 虚拟导航键高度)/2
                layoutParams.leftMargin = (int) ((width-(height * 1.778)) - statusBarHeight - navigationBarHeight)/2;
                //调整surfaceView比例
                playerView.getSurfaceView().setLayoutParams(layoutParams);
                //横屏时控制层比例 要与surfaceView保持一致
                horPlayerView.setLayoutParams(layoutParams);
            }

        } else {
            //视频窗口父布局 宽度 * 0.563(16:9)
            playerViewParent.setLayoutParams(new LinearLayout.LayoutParams(width, (int) (width * (0.563))));
            
            if (height/width >= 1.97f){
                //全面屏
                //调整surfaceView比例
                playerView.getSurfaceView().setLayoutParams(new FrameLayout.LayoutParams(width, (int) (width * (0.563))));  
            }
            
        }

    }

在横竖屏切换时调用

android 按比例布局 安卓比例修改16:9_视频变形

其他用到的方法也奉上

/**
     * 获取状态栏高度
     * @return
     */
    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height",
                "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
/**
     * 获取是否存在NavigationBar
     * @param context
     * @return
     */
    public boolean checkDeviceHasNavigationBar(Context context) {
        boolean hasNavigationBar = false;
        Resources rs = context.getResources();
        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        try {
            Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
            Method m = systemPropertiesClass.getMethod("get", String.class);
            String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                hasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                hasNavigationBar = true;
            }
        } catch (Exception e) {
        }
        return hasNavigationBar;
    }
/**
     * 获取虚拟功能键高度
     * @param context
     * @return
     */
    public int getVirtualBarHeigh(Context context) {
        int vh = 0;
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        try {
            @SuppressWarnings("rawtypes")
            Class c = Class.forName("android.view.Display");
            @SuppressWarnings("unchecked")
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            vh = dm.heightPixels - windowManager.getDefaultDisplay().getHeight();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return vh;
    }

调用,如果其他有页面用到这个数据的 可以跟我一样写在BaseActivity,或者单独另写一个BaseActivity。

android 按比例布局 安卓比例修改16:9_android_02