android WebView常见功能处理(视频全屏,错误页等)
2017-04-13 13:59
651 查看
虽然android的webview现在可以直接接入腾讯的X5或者UC WebView SDK,都号称更稳定更快和适配更方便。但实际开发中不一定所有的产品都会接入它们,像x5在视频全屏时会有QQ浏览器的下载链接(我没查文档,不知道可不可以去掉的),一不小心点到就去下载了,且在我使用的时候就适配而言并没有比原生的好多少。不论怎么说多会点东西总不会亏。本篇文章讲的是1、修改WebView原本的错误页处理2、页面跳转的处理3、页面加载进度条的处理4、视频全屏处理。主要实现方式就是处理WebViewClient和WebChromeClient。不喜欢看说明的可以直接拉到底部有demo下载地址。本文地址:http://blog.csdn.net/lanqi_x/article/details/70157453
一、修改WebView原本的错误页处理和页面跳转的处理,这两个功能是在WebViewClient中处理。
1、页面跳转的处理基本上所有的android开发者都知道怎么处理,就不多说了,直接贴代码
2、修改WebView原本的错误页,这个我的处理思路是当页面加载错误时,会调用onReceivedError方法,在这个时候我把WebView给隐藏了,然后拿到WebView的父控件,在对于WebView的位置上加入我自己定义的错误页布局。当重新加载没有错误时就把这个错误页移除掉,再将WebView显示处理。来吧,贴一小段代码吧!
二、页面加载进度条的处理和视频全屏处理,这两个我是放在WebChromeClient中处理的。
1、先说简单的加载进度条的处理。WebChromeClient有个onProgressChanged方法,这里会传进页面加载的进度,在这里我们就可以处理进度条了。
2、视频全屏处理,这里用到了WebChromeClient的onShowCustomView和onHideCustomView方法,分别是用户点击了全屏和关闭全屏时调用。我的处理方式是这样的,onShowCustomView会传个参数View进来,这个view就是视频播放的view,我们见他放进我们要显示的ViewGrop就可以了,而在onHideCustomView中将其移除就行。
我采取外部传参数的方式,即使用这个WebChromeClient时传个FrameLayout进来,在全屏的时候FrameLayout.add(view);代码如下:
其实如果所有的地方显示的界面比较统一的话可以采取约定大于配置的思路,就是约定好如要使用这个全屏功能,那个这个界面的根布局必须是FrameLayout,那么videoView就可以写死在WebChromeClient内,通过获取webView所在布局的根布局,再将videoView给add进去就行了, 简单代码如下,但未经测试,仅供参考:
下载地址https://github.com/lanqi-x/webViewPro
一、修改WebView原本的错误页处理和页面跳转的处理,这两个功能是在WebViewClient中处理。
1、页面跳转的处理基本上所有的android开发者都知道怎么处理,就不多说了,直接贴代码
/** * 点击网页中按钮时,让其还在原页面打开 */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("http")) { if (loadNewUrlListener != null) { if (!loadNewUrlListener.loadNewUrl(view, url)) { view.loadUrl(url); } } else { view.loadUrl(url); } } else { // 非http和https请求丢给系统处理,比如拨打电话等 try { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); view.getContext().startActivity(intent); } catch (Exception e) { // 没有安装对应的应用会抛异常 e.printStackTrace(); } } return true; }
2、修改WebView原本的错误页,这个我的处理思路是当页面加载错误时,会调用onReceivedError方法,在这个时候我把WebView给隐藏了,然后拿到WebView的父控件,在对于WebView的位置上加入我自己定义的错误页布局。当重新加载没有错误时就把这个错误页移除掉,再将WebView显示处理。来吧,贴一小段代码吧!
/** * 页面加载结束 * * @param view * @param url */ @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); hideErrorPage(view); if (pagefinish != null) { pagefinish.pageFinished(view, url); } pageIsFinished = true; } /** * 加载错误 * * @param view * @param request * @param error */ @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { showErrorPage(view); } /** * 加载错误 * * @param view * @param errorCode * @param description * @param failingUrl */ @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { showErrorPage(view); } private View mErrorView; private boolean loadError; /** * 显示错误页 * * @param webView */ protected void showErrorPage(final WebView webView) { if (customizeErrorPage) { ViewGroup viewParent = (ViewGroup) webView.getParent(); if (mErrorView == null) { mErrorView = View.inflate(webView.getContext(), R.layout.view_webview_error, null); mErrorView.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { webView.reload(); } }); } int i = viewParent.indexOfChild(webView); if (viewParent.indexOfChild(mErrorView) == -1) { ViewGroup.LayoutParams lp = webView.getLayoutParams(); webView.setVisibility(View.GONE); viewParent.addView(mErrorView, i, lp); } loadError = true; } } /**** * 隐藏错误页 */ protected void hideErrorPage(final WebView webView) { if (customizeErrorPage && mErrorView != null) { if (!loadError) { ViewGroup viewParent = (ViewGroup) mErrorView.getParent(); if (viewParent != null) { int i = viewParent.indexOfChild(mErrorView); if (i != -1) { viewParent.removeView(mErrorView); } } loadError = false; mErrorView = null; // 防止较卡的手机闪现WebView的错误页 webView.postDelayed(new Runnable() { @Override public void run() { webView.setVisibility(View.VISIBLE); } }, 200); } } }
二、页面加载进度条的处理和视频全屏处理,这两个我是放在WebChromeClient中处理的。
1、先说简单的加载进度条的处理。WebChromeClient有个onProgressChanged方法,这里会传进页面加载的进度,在这里我们就可以处理进度条了。
/**页面加载进度处理 * @param view * @param newProgress */ @Override public void onProgressChanged(WebView view, int newProgress) { handle.removeMessages(1); if (progressBar != null) { if (progressBar.getProgress() == 0) { progressBar.setVisibility(View.VISIBLE); } for (int i = this.progressBar.getProgress(); i <= newProgress; i++) { Message message = new Message(); message.what = 1; message.obj = i; handle.sendMessageDelayed(message, i * 5); } } super.onProgressChanged(view, newProgress); } private Handler handle = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); progressBar.setProgress((int) msg.obj); if ((int) msg.obj == 100) { progressBar.setVisibility(View.GONE); progressBar.setProgress(0); } } };
2、视频全屏处理,这里用到了WebChromeClient的onShowCustomView和onHideCustomView方法,分别是用户点击了全屏和关闭全屏时调用。我的处理方式是这样的,onShowCustomView会传个参数View进来,这个view就是视频播放的view,我们见他放进我们要显示的ViewGrop就可以了,而在onHideCustomView中将其移除就行。
我采取外部传参数的方式,即使用这个WebChromeClient时传个FrameLayout进来,在全屏的时候FrameLayout.add(view);代码如下:
@Override public void onShowCustomView(View view, CustomViewCallback callback) { if (videoView == null) { super.onShowCustomView(view, callback); } else { if (view instanceof FrameLayout) a720 { FrameLayout frameLayout = (FrameLayout) view; View focusedChild = frameLayout.getFocusedChild(); // 更改状态 this.isVideoFullscreen = true; this.videoViewContainer = frameLayout; this.videoViewCallback = callback; // 隐藏布局 noVideoView.setVisibility(View.INVISIBLE); // 将网页视频的View ,加入显示的地方 videoView.addView(videoViewContainer, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); videoView.setVisibility(View.VISIBLE); // 添加视频播放事件 if (focusedChild instanceof android.widget.VideoView) { // android.widget.VideoView (typically API level <11) android.widget.VideoView videoView = (android.widget.VideoView) focusedChild; // Handle all the required events videoView.setOnPreparedListener(this); videoView.setOnCompletionListener(this); videoView.setOnErrorListener(this); } // Notify full-screen change if (toggledFullscreenCallback != null) { toggledFullscreenCallback.toggledFullscreen(true); } }else { super.onShowCustomView(view, callback); } } } @Override @SuppressWarnings("deprecation") public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) // Available in API level 14+, deprecated in API level 18+ { onShowCustomView(view, callback); } @Override public void onHideCustomView() { if (videoView == null) { super.onHideCustomView(); } else { if (isVideoFullscreen) { videoView.setVisibility(View.INVISIBLE); videoView.removeView(videoViewContainer); noVideoView.setVisibility(View.VISIBLE); // Call back (only in API level <19, because in API level 19+ with chromium webview it crashes) if (videoViewCallback != null && !videoViewCallback.getClass().getName().contains(".chromium.")) { videoViewCallback.onCustomViewHidden(); } isVideoFullscreen = false; videoViewContainer = null; videoViewCallback = null; if (toggledFullscreenCallback != null) { toggledFullscreenCallback.toggledFullscreen(false); } }else { super.onHideCustomView(); } } }
其实如果所有的地方显示的界面比较统一的话可以采取约定大于配置的思路,就是约定好如要使用这个全屏功能,那个这个界面的根布局必须是FrameLayout,那么videoView就可以写死在WebChromeClient内,通过获取webView所在布局的根布局,再将videoView给add进去就行了, 简单代码如下,但未经测试,仅供参考:
@Override public void onShowCustomView(View view, CustomViewCallback callback) { ViewGroup parentView= (ViewGroup) webView.getParent(); while (parentView.getParent() != null){ parentView = (ViewGroup) parentView.getParent(); } FrameLayout videoView=new FrameLayout (webView.getContext()); videoView.setBackgroundColor(0x000000); videoView.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); parentView.addView(videoView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); }
下载地址https://github.com/lanqi-x/webViewPro
相关文章推荐
- Android解决WebView的定位功能、视频全屏播放、下载功能、页面Url的处理、进度条处理
- Android中WebView的定位功能、视频全屏播放、下载功能、页面Url的处理、进度条处理
- [转]Android WebView播放视频(包括全屏播放),androidwebview
- Android WebView页面结束后视频播放还有声音问题处理
- Android使用WebView全屏播放网页视频
- android WebView实现播放网络视频以及全屏显示
- Android WebView 总结 —— 硬件加速使用HTML5播放视频及全屏方案
- android 4.0以上WebView不能全屏播放视频的解决办法
- Android WebView视频全屏显示解决方案
- Android中加载WebView的H5全屏视频播放
- Android webview实现h5视频全屏播放兼容Android7.0,自己添加webview库兼容全部版本
- android webview 播放视频 全屏问题
- 菜鸟学android——webview播放网络视频,由竖屏转换为横屏全屏播放
- android webview 使用以及一些常见的异常处理
- 关于Android中使用WebView播放网络视频不能全屏的问题
- android webview: 视频全屏播放按返回页面被放大的问题
- android webview 使用以及一些常见的异常处理
- Android webview全屏播放HTML5中的视频
- Android中使用WebView全屏播放视频时home键不起作用的问题解决
- Android WebView 真正播放视频 全屏 横屏播放