我用的播放器是KMedia,一个开源的播放器,链接如下
https://github.com/BlackQi/KMedia
我个人觉得还是很好用的,支持定制。现在遇到一个问题就是播放时横屏铺满全屏视频被拉伸的问题(我们的视频比例为16:9 也就是1.778:1)。由于该播放器没有提供屏幕比例调整的api,所以就只能自己搞了。
思路,原本是想直接一刀切:横屏时把window的尺寸调整一下,那window所包含的内容不就直接改了吗 也不用过多的调整UI,而且好用的一点是window调整之后会以屏幕居中,就不用手动调整窗口的位置了。
调整window大小可参考https://blog.youkuaiyun.com/chuoshao2508/article/details/100823630
需要注意的是 如果有虚拟按键的情况,以上链接获取的尺寸是不准确的,可以这样搞
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非全屏时是不能正常操作状态栏的,具体参考https://blog.youkuaiyun.com/u013541140/article/details/88892557
我没有看有没有其他的方法能修改状态栏,时间有限,直接改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))));
}
}
}
在横竖屏切换时调用
其他用到的方法也奉上
/**
* 获取状态栏高度
* @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。