網(wǎng)站開(kāi)發(fā)績(jī)效指標(biāo)奇葩網(wǎng)站100個(gè)
去年雙十一有個(gè)直播的需求,聽(tīng)起來(lái)很簡(jiǎn)單,技術(shù)也都很成熟,但是真的開(kāi)始實(shí)現(xiàn)后,還是有不少坑的,首先第一個(gè)uc內(nèi)核不支持webRTC協(xié)議,需要重新開(kāi)發(fā)chrome內(nèi)核的webview,其次webview全屏處理、懸浮窗恢復(fù)同步、輸入框被被輸入法遮蓋等問(wèn)題,都是坑,小子挨個(gè)踩過(guò),查閱很多前輩資料,把能夠即插即用的部分整理出來(lái),以資來(lái)者。
原理
H5在調(diào)用系統(tǒng)全屏和恢復(fù)接口時(shí),會(huì)觸發(fā)WebChromeClient
的onShowCustomView(View, CustomViewCallback)
和onHideCustomView()
接口,所以只要在兩個(gè)方法中分別實(shí)現(xiàn)橫豎屏切換和全屏展示和隱藏即可。
其中需要注意的:
1、在onShowCustomView()
中有個(gè)入?yún)?code>CustomViewCallback,這回調(diào)需要在全屏恢復(fù)時(shí)調(diào)用,以告知H5解決全屏展示。
2、布局中增加一個(gè)充滿(mǎn)屏幕的控件,用以承載全屏的展示。
源碼注釋
/*** Notify the host application that the current page has entered full screen mode. After this* call, web content will no longer be rendered in the WebView, but will instead be rendered* in {@code view}. The host application should add this View to a Window which is configured* with {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} flag in order to* actually display this web content full screen.** <p>The application may explicitly exit fullscreen mode by invoking {@code callback} (ex. when* the user presses the back button). However, this is generally not necessary as the web page* will often show its own UI to close out of fullscreen. Regardless of how the WebView exits* fullscreen mode, WebView will invoke {@link #onHideCustomView()}, signaling for the* application to remove the custom View.** <p>If this method is not overridden, WebView will report to the web page it does not support* fullscreen mode and will not honor the web page's request to run in fullscreen mode.** <p class="note"><b>Note:</b> if overriding this method, the application must also override* {@link #onHideCustomView()}.** @param view is the View object to be shown.* @param callback invoke this callback to request the page to exit* full screen mode.*/
public void onShowCustomView(View view, CustomViewCallback callback) {};
Google源碼的注釋寫(xiě)的確實(shí)清楚,這個(gè)方法就是做了一件事兒: 更改渲染對(duì)象,新對(duì)象通過(guò)view傳給原生。
但在調(diào)用時(shí),需要注意:
- 宿主APP要配置全屏屬性
- 在關(guān)閉全屏?xí)r,記得調(diào)用
#onHideCustomView#onCustomViewHidden()
實(shí)現(xiàn)
布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><WebViewandroid:id="@+id/float_webview"android:layout_width="match_parent"android:layout_height="match_parent" /><FrameLayoutandroid:id="@+id/float_frameLayout"android:layout_width="match_parent"android:layout_height="match_parent"></FrameLayout>
</LinearLayout>
Java實(shí)現(xiàn)
private void setWebView(){mWebChromeClient = new WebChromeClient() {@Overridepublic void onShowCustomView(View view, CustomViewCallback callback) {super.onShowCustomView(view, callback);if (mCustomView != null) {callback.onCustomViewHidden(); // 通知H5全屏關(guān)閉return;}mCustomView = view; // 緩存全屏視圖mFrameLayout.addView(mCustomView); // 向全屏控件添加全屏視圖mCustomViewCallback = callback;mWebview.setVisibility(View.GONE); // 將已有webview控件隱藏setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 切換橫屏}@Overridepublic void onHideCustomView() {webview.setVisibility(View.VISIBLE);if (mCustomView == null) {return;}mCustomView.setVisibility(View.GONE);mFrameLayout.removeView(mCustomView);mCustomViewCallback.onCustomViewHidden(); // 通知H5全屏關(guān)閉mCustomView = null;setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 切換豎屏super.onHideCustomView();}};mWebview.setWebChromeClient(mWebChromeClient);
}
參考
Android WebView 全屏播放視頻