WebView网页视频统一全屏播放及横竖屏切换
Posted ZhangQiang-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebView网页视频统一全屏播放及横竖屏切换相关的知识,希望对你有一定的参考价值。
WebView 支持 html5 video 进行全屏播放及横竖屏自动切换
1.检查androidManifest.xml清单文件,WebView控件所在的Activity配置信息;检查Activity的主题是否NoActionBar了。
## 犯错的错误写成了如下: android:configChanges="orientation|keyboardHidden" -->
## 正确的写法: android:configChanges="orientation|screenSize|keyboardHidden"
或者: android:configChanges="keyboard|keyboardHidden|orientation|screenSize|navigation|fontScale|uiMode|screenLayout"
注:
总结:
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法
(一次生命周期)如切换成横屏: onSaveInstanceState-->onPause-->onStop-->onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume-->
2.初始化webview及各项setting(自己去根据需求初始化)
//常用:
WebSettings ws = webView.getSettings();
// 网页内容的宽度是否可大于WebView控件的宽度
ws.setLoadWithOverviewMode(false);
// 保存表单数据
ws.setSaveFormData(true);
// 是否应该支持使用其屏幕缩放控件和手势缩放
ws.setSupportZoom(true);
ws.setBuiltInZoomControls(true);
ws.setDisplayZoomControls(false);
// 启动应用缓存
ws.setAppCacheEnabled(true);
// 设置缓存模式
ws.setCacheMode(WebSettings.LOAD_DEFAULT);
// setDefaultZoom api19被弃用
// 设置此属性,可任意比例缩放。
ws.setUseWideViewPort(true);
// 不缩放
webView.setInitialScale(100);
// 告诉WebView启用javascript执行。默认的是false。
ws.setJavaScriptEnabled(true);
// 页面加载好以后,再放开图片
ws.setBlockNetworkImage(false);
// 使用localStorage则必须打开
ws.setDomStorageEnabled(true);
// 排版适应屏幕
ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
// WebView是否新窗口打开(加了后可能打不开网页)
ws.setSupportMultipleWindows(true);
// webview从5.0开始默认不允许混合模式,https中不能加载http资源,需要设置开启。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
ws.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
/** 设置字体默认缩放大小(改变网页字体大小,setTextSize api14被弃用)*/
ws.setTextZoom(100);
3.给WebView设置WebViewClient:
思路:在onShowCustomView方法中,讲获取到的view放到当前Activity的最上方,在onHideCustomView中,将之前的view隐藏或者删除,将原来被覆盖的webview放回来。并结束播放。
webView.setWebViewClient(new MyWebViewClient(this));
//webview视频全屏下videoContainer ---(自己在webview所在布局里定义一个frameLayout作为盛放view的容器) private CustomVideoContainerFramLayout mVideoContainer; //webview全屏时传入的view private View mXCustomView; public class NewsWebViewChromeClient extends WebChromeClient /** * webview全屏回调 * * @param view * @param callback */ @Override public void onShowCustomView(View view, CustomViewCallback callback) super.onShowCustomView(view, callback); //设置全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //设置横屏 int requestedOrientation = getRequestedOrientation(); if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE) //反横屏下设置跟随传感器 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); else //其他情况设置横屏 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); if (webview != null) webview.setVisibility(View.GONE); if (mXCustomView != null) callback.onCustomViewHidden(); return; fullViewAddView(view); mXCustomView = view; mVideoContainer.setVisibility(View.VISIBLE); //设置隐藏虚拟按键/导航键(避免造成全屏时布局不满) mXCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE); /** * webview 退出全屏回调 */ @Override public void onHideCustomView() if (mXCustomView == null) // 不是全屏播放状态 return; //取消全屏 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //恢复虚拟键 mXCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); //恢复为用户方向 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER); mXCustomView.setVisibility(View.GONE); if (mVideoContainer != null) mVideoContainer.removeView(mXCustomView); mXCustomView = null; mVideoContainer.setVisibility(View.GONE); if (webview != null) webview.setVisibility(View.VISIBLE); public void fullViewAddView(View view) FrameLayout decor = (FrameLayout) getWindow().getDecorView(); mVideoContainer = new CustomVideoContainerFramLayout(this); mVideoContainer.addView(view); decor.addView(mVideoContainer);
开启重力感应自动切换屏幕
使用方法:
//重力传感器
private MySensorHelper sensorHelper;
private void initData()
//初始化重力感应,传入activity
sensorHelper = new MySensorHelper(this);
//开启重力感应
sensorHelper.enable();
@Override
protected void onDestroy()
//关闭重力传感器
if (sensorHelper != null)
sensorHelper.disable();
4.开启重力感应自动切换屏幕
使用方法:
//重力传感器
private MySensorHelper sensorHelper;
private void initData()
//初始化重力感应,传入activity
sensorHelper = new MySensorHelper(this);
//开启重力感应
sensorHelper.enable();
@Override
protected void onDestroy()
//关闭重力传感器
if (sensorHelper != null)
sensorHelper.disable();
直接上代码:具体可根据需求进行更改
/**
* @author : Created by zhangqiang
* @date : on 2018/9/30.
* desc :通过重力传感器切换横竖屏放向
* 在activity的ondestory()方法里面或者back键的监听里面禁用屏幕监听
*/
public class MySensorHelper
private static final String TAG = "MySensorHelper";
private OrientationEventListener mOrientationEventListener;
private WeakReference<Activity> mActivityWeakRef;
private Activity mActivity;
//竖直锁定
private boolean isPortLock = false;
//横屏锁定
private boolean isLandLock = false;
//是否在全屏模式
private boolean isFullScreen = false;
//屏幕方向
private int mOrientation = -1;
//屏幕状态 (横屏 / 竖屏等)
private ScreenState mScreenState;
public MySensorHelper(final Activity activity)
this.mActivityWeakRef = new WeakReference(activity);
mActivity = activity;
//横屏感应
this.mOrientationEventListener = new OrientationEventListener(activity, SensorManager.SENSOR_DELAY_NORMAL)
@Override
public void onOrientationChanged(int orientation)
if (BuildConfig.DEBUG)
Log.v(MySensorHelper.TAG, "mOrientationEventListener:" + orientation);
// //若未开启重力感应则不作处理
// if (!ishaveSensor())
// return;
//
//横屏感应
if (orientation < 100 && orientation > 80 || orientation < 280 && orientation > 260)
if (!MySensorHelper.this.isLandLock)
Activity mActivity = (Activity) MySensorHelper.this.mActivityWeakRef.get();
if (mActivity != null)
if (orientation < 280 && orientation > 260)
/* 在全屏模式下 或者 开启了重力感应下 才进入旋转 */
if (isFullScreen || ishaveSensor())
//设置横屏
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
if (BuildConfig.DEBUG)
Log.w(MySensorHelper.TAG, "转到了横屏##################");
else if (orientation < 100 && orientation > 80)
//在全屏模式下 或者 开启了重力感应下 才进入旋转
if (isFullScreen || ishaveSensor())
//设置反向横屏
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
if (BuildConfig.DEBUG)
Log.w(MySensorHelper.TAG, "转到了横屏-反向 ##################");
isLandLock = true;
isPortLock = false;
// 竖屏感应
if (orientation < 10 || orientation > 350 || orientation < 190 && orientation > 170)
if (!MySensorHelper.this.isPortLock)
Activity mActivity = (Activity) MySensorHelper.this.mActivityWeakRef.get();
if (mActivity != null)
if (isFullScreen)
//全屏下 若未开启方向锁定 调用webview全屏消失
if (mScreenState != null && ishaveSensor())
mScreenState.OnScreenPortrait();
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
if (BuildConfig.DEBUG)
Log.w(MySensorHelper.TAG, "全屏下 转到了竖屏!!!!!!!!!!!!!!!!!!!!!!");
else
//非全屏下才处理 感应旋转
mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
if (BuildConfig.DEBUG)
Log.w(MySensorHelper.TAG, "非全屏下 转到了竖屏!!!!!!!!!!!!!!!!!!!!!!");
isPortLock = true;
isLandLock = false;
;
/**
* 禁用切换屏幕的开关
*/
public void disable()
Log.e(TAG, "disable");
//禁用横屏感应
if (mOrientationEventListener != null)
this.mOrientationEventListener.disable();
/**
* 开启横竖屏切换的开关
*/
public void enable()
//横屏感应
if (mOrientationEventListener != null)
this.mOrientationEventListener.enable();
/**
* 设置竖屏是否上锁,true锁定屏幕,fanle解锁
*
* @param lockFlag
*/
public void setPortLock(boolean lockFlag)
this.isPortLock = lockFlag;
/**
* 设置横屏是否锁定,true锁定,false解锁
*
* @param isLandLock
*/
public void setLandLock(boolean isLandLock)
this.isLandLock = isLandLock;
/**
* 设置当前是否全屏
*
* @param fullScreen
*/
public void setFullScreen(boolean fullScreen)
this.isFullScreen = fullScreen;
/**
* 获取系统重力感应的开关状态
* 0表示关闭,1表示开启
*/
public boolean ishaveSensor()
int sensor = 0;
try
sensor = Settings.System.getInt(mActivity.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION);
catch (Settings.SettingNotFoundException e)
e.printStackTrace();
if (sensor == 0)
return false;
else
return true;
/**
* Activity当前屏幕方向的属性值
*
* @return 0 横屏 , 1 竖屏
*/
public int getOrientation()
if (mActivity != null && !mActivity.isFinishing())
mOrientation = mActivity.getResources().getConfiguration().orientation;
return mOrientation;
return -1;
/**
* 设置Activity的的屏幕方向属性值
*
* @param orientation ActivityInfo.xxx 0 横屏 , 1 竖屏 如ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
* <p>
* screenOrientations属性共有7中可选值(常量定义在 android.content.pm.ActivityInfo类中 ) :
* 0-landscape:横屏(风景照) ,显示时宽度大于高度;
* portrait:竖屏 (肖像照) , 显示时 高 度大于 宽 度 ;
* user:用户当前的首选方向;
* behind:继承Activity堆栈中当前Activity下面的那个Activity的方向;
* sensor:由物理感应器决定显示方向,它取决于用户如何持有设备,当 设备 被旋转时方向会随之变化——在横屏与竖屏之间;
* nosensor:忽略物理感应器——即显示方向与物理感应器无关,不管用户如何旋转设备显示方向都不会随着改变("unspecified"设置除外);
* unspecified :未指定,此为默认值,由Android系统自己选择适当的方向,选择策略视具体设备的配置情况而定,因此不同的设备会有不同的方向选择;
* 以上配置值会反映在Activity.getRequestedOrientation()方法的返回值中,与之对应的setRequestedOrientation()方法可以通过API的方式动态改变该属性的值,如以下示例将在横屏/竖屏两个方向上进行切换
*/
public void setOrientation(int orientation)
mOrientation = orientation;
mActivity.setRequestedOrientation(orientation);
/**
* 设置屏幕状态(横屏/竖屏监听)
*
* @param screenState
*/
public void setScreenStateListener(ScreenState screenState)
mScreenState = screenState;
/**
* 屏幕状态接口类
*/
public interface ScreenState
/**
* 竖屏状态
*/
void OnScreenPortrait();
相关参考:
WebView实现全屏播放的一种方法 https://www.jianshu.com/p/d70a73594b71
WebView中的视频全屏4种方法,特别是腾讯视频,真正解决全屏问题 https://www.jianshu.com/p/4aed5c1230dc
WebView 支持 Html5 video 进行全屏播放 https://www.jianshu.com/p/2dd60e6bd798
Android 关于WebView全方面的使用(项目应用篇) --- github:https://github.com/youlookwhat/WebViewStudy
Android webview网页视频无法全屏解决(onShowCustomView不调用)
android webview: 视频全屏播放按返回页面被放大的问题
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" :
系统重力感应开关和Activity的屏幕方向属性值之间的区别
让android程序根据重力感应旋转屏幕(支持4个方向旋转)
Android-加速传感器或者OrientationEventListener做横竖屏切换
Android手势检测——GestureDetector全面分析 https://blog.csdn.net/totond/article/details/77881180
Android视频播放器的手势控制实现 https://blog.csdn.net/totond/article/details/77881403 Git : https://github.com/totond/GestureTest
触摸事件与手势监听--Android GestureDetector详解 https://blog.csdn.net/hpk1994/article/details/51224228
Android设置屏幕亮度的两种方式 : https://blog.csdn.net/jiangxuelei_2015/article/details/51243575
Android设置屏幕亮度 : https://blog.csdn.net/wzy_1988/article/details/49472611
Android 6 完美解决 WRITE_SETTINGS 权限设置问题 https://www.jianshu.com/p/0b880871b887
webview 播放H5视频问题 黑屏 只有声音没有画面 https://www.cnblogs.com/qianyukun/p/4792533.html
hardwareAccelerated 硬件加速详解 https://blog.csdn.net/mafei852213034/article/details/50678493
详解Android开发中硬件加速支持的使用方法 https://www.jb51.net/article/79841.htm
以上是关于WebView网页视频统一全屏播放及横竖屏切换的主要内容,如果未能解决你的问题,请参考以下文章