WebView 視訊播放,全屏按鈕顯示不出來,全屏後不能播放視訊
最近專案的一個需求,需要在Webview 裡面播放視訊遇到了一些問題:
視訊可以正常播放但是,視訊底部的全屏按鈕沒了,只有一個音量按鈕。修改後,點選全屏,視訊不能播放。
接下來一 一解決:
問題1 :沒有全屏按鈕:
如圖:可以看到只有一個音量按鈕,沒有全屏按鈕。
查了一下資料,文件上寫著支援視訊播放的條件:
In order to support inline HTML5 video in your application, you need to have hardware acceleration turned on, and set a WebChromeClient. For full screen support, implementations of onShowCustomView(View, WebChromeClient.CustomViewCallback) and onHideCustomView() are required, getVideoLoadingProgressView() is optional.
意思就是:
1、要開啟硬體加速
2、設定 WebChromeClient ,並實現 onShowCustomView() 方法和onHideCustomView()方法。
3、要支援全屏
接下來就是解決問題:
1、首先開啟硬體加速
在AndroidMainfest.xml中,當前webView所在類的標籤中新增 : android:hardwareAccelerated="true"
<activity android:name="..." android:hardwareAccelerated="true"/>
2、設定 WebChromeClient
我們新增一個內部類,實現 WebChromeClient, 並複寫其中的方法
private class MyWebChromeClient extends WebChromeClient { // 全屏的時候呼叫 @Override public void onShowCustomView(View view, CustomViewCallback callback) { super.onShowCustomView(view, callback); } // 切換為豎屏的時候呼叫 @Override public void onHideCustomView() { super.onHideCustomView(); } }
寫到這裡全屏按鈕就已經顯示出來了。當然,我們我們還要設定一下WebView 的相關屬性
/**
* 設定webView 相關屬性
* */
private void initWebView() {
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);// 設定支援javascript指令碼
webview.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);//設定webview快取模式
webview.setVerticalScrollBarEnabled(false); // 取消Vertical ScrollBar顯示
webview.setHorizontalScrollBarEnabled(false); // 取消Horizontal ScrollBar顯示
//設定自適應螢幕,兩者合用
webview.getSettings().setUseWideViewPort(true);
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setAllowFileAccess(true);// 允許訪問檔案
webview.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webview.setFocusable(false); // 去掉超連結的外邊框
webview.getSettings().setDefaultTextEncodingName("GBK");//設定文字編碼(根據頁面要求設定: utf-8)
webview.setWebChromeClient(new MyWebChromeClient());
}
然後看一下效果:
問題2:設定全屏後,視訊不能播放
全屏按鈕出來後,點選全屏,會呼叫 onShowCustomView() 方法。我們在這個方法中設定橫屏的方法,即可實現全屏
//設定橫屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
但是我設定後,發現無法播放視訊,只顯示一個黑頁面
查了下相關資料後,發現
public void onShowCustomView(View view, CustomViewCallback callback)
這個方法,在設定全屏後 會在引數 view 上顯示播放的視訊。所以,當設定全屏後,需要讓這個view顯示到最前方。
解決:我們可以在佈局檔案中,新增一個和webview 同級的 Framlaoyout ,用來存放這個檢視
xml 檔案:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fl_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout >
WebChromeClient 具體實現
public class HelpActivity extends TitleBarActivity {
private WebView webview = null;
// h5 地址
private String reurl = "";
// 用來顯示視訊的佈局
private FrameLayout mLayout;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
mLayout = (FrameLayout) findViewById(R.id.fl_video);
webview = (WebView) findViewById(R.id.webview);
inieWebView();
}
/**
* 設定webView 相關屬性
*/
private void initWebView() {
WebSettings setting= webview.getSettings();
setting.setJavaScriptEnabled(true);// 設定支援javascript指令碼
setting.setCacheMode(WebSettings.LOAD_NO_CACHE);//設定快取模式
webview.setVerticalScrollBarEnabled(false); // 取消Vertical ScrollBar顯示
webview.setHorizontalScrollBarEnabled(false); // 取消Horizontal ScrollBar顯示
//設定自適應螢幕,兩者合用
setting.setUseWideViewPort(true);
setting.setLoadWithOverviewMode(true);
setting.setAllowFileAccess(true);// 允許訪問檔案
setting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setting.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webview.setFocusable(false); // 去掉超連結的外邊框
setting.setDefaultTextEncodingName("GBK");//設定文字編碼(根據頁面要求設定)
webview.setWebChromeClient(new MyWebChromeClient());
}
private class MyWebChromeClient extends WebChromeClient {
private CustomViewCallback mCustomViewCallback;
// 橫屏時,顯示視訊的view
private View mCustomView;
// 點選全屏按鈕時,呼叫的方法
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
//如果view 已經存在,則隱藏
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomView = view;
mCustomView.setVisibility(View.VISIBLE);
mCustomViewCallback = callback;
mLayout.addView(mCustomView);
mLayout.setVisibility(View.VISIBLE);
mLayout.bringToFront();
//設定橫屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
// 取消全屏呼叫的方法
@Override
public void onHideCustomView() {
super.onHideCustomView();
if (mCustomView == null) {
return;
}
mCustomView.setVisibility(View.GONE);
mLayout.removeView(mCustomView);
mCustomView = null;
mLayout.setVisibility(View.GONE);
try {
mCustomViewCallback.onCustomViewHidden();
} catch (Exception e) {
}
titleView.setVisibility(View.VISIBLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//豎屏
}
}
/**
* 橫豎屏切換監聽
*/
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
switch (config.orientation) {
case Configuration.ORIENTATION_LANDSCAPE:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
break;
case Configuration.ORIENTATION_PORTRAIT:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
webview.destroy();
webview = null;
}
}
還需要在 AndroidMainfest.xml 中設定該 Activity相關屬性,即橫豎屏切換的時候,不進行生命週期的切換
<activity
android:name=".HelpActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:hardwareAccelerated="true"
android:screenOrientation="portrait"
/>
到這裡就大功告成!
還有一點需要注意: 當我們播放視訊後,如果直接退出,會發現後臺仍然在播放。
我們可以在 onDestory 方法中,對webView進行銷燬