产品有个需求,要在App中打开天猫购物的链接,并且要隐藏掉H5页面的某些内容,让用户只能浏览商品,而不能购买,这个就需要在Java代码中操作WebView,让H5页面加载完成后能够隐藏掉某些内容。
首先我们来看一下天猫购物的链接地址:
https://market.m.taobao.com/apps/market/need/yxIndex.html
,使用WebView打开后页面如下:
这个页面是让用户选择商品的界面,不需要修改,点击某个商品,进入商品详情页面:
需要隐藏的就是这个页面的底部栏,这样用户就只能看商品信息而不能操作该商品了,现在我们分析一下思路,是否可以等页面加载完成后,执行Js代码,找到底部栏并将其隐藏呢?这个是最直接的思路,下面我们就按照这个思路分析,按照这种思路要解决几个问题:
1、需要知道何时页面加载完成了;
2、需要知道如何在Java代码中执行Js代码;
3、需要知道如何利用Js代码找到页面中的底部栏并将其隐藏。
解决了上面三个问题,问题也就基本解决了。首先我们来看一下第一个问题,如何监听WebView加载页面完成了。
1、监听页面加载完成
一般的,我们可以给WebView设置WebViewClient,在WebViewClient的onPageFinished方法中监听页面加载完成。代码如下:
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// 页面加载完成
2、在Java代码中执行Js代码
我们可以使用WebView提供的loadUrl(String)方法来让Java代码执行Js代码,格式如下:
//定义javaScript方法
String javascript = "javascript:function hideBottom() { "
+ "}";
//加载方法
mWebView.loadUrl(javascript);
//执行方法
mWebView.loadUrl("javascript:hideBottom();");
上面的代码中,我们首先定义了一个js方法hideBottom,然后调用WebView的loadUrl加载该方法,最后再执行该方法即可。
3、在页面中找到底部栏并将其隐藏
在H5页面中找到某个元素还是有很多方法的,比如getElementById()、getElementsByClassName()、getElementsByTagName()等,具体根据页面来选择,我们先在浏览器中查看页面源码,找到底部栏,然后在确定使用哪种方式获得底部栏,在chrome浏览器中点击一个商品查看详情,按F12进入开发者模式调试页面:
点击最左边按钮
这样,当鼠标在页面中移动到了某个元素时,右边会显示出对应的代码,我们找到了底部栏对应的源码如下:
可以看到其并没有设置id,而是设置了class,所以这里我们通过getElementsByClassName()找到底部栏元素,我们可以在浏览器里面调试一下,看能不能找到底部栏并隐藏。我们切换到Console栏,输入如下代码并执行:
document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')[0].style.display='none'
发现页面中的底部栏被隐藏掉了
上面Js的代码,首先通过getElementByClassName方法找到'class'为'weex-div weex-ct bpu_bottom_toolbar weex-fixed'的所有元素,返回的是一个数组,在这个页面中,只有底部栏的'class'为'weex-div weex-ct bpu_bottom_toolbar weex-fixed',所以取数组中的第一个元素对应的就是底部栏元素,然后将底部栏的display属性设置为'none',表示底部栏不显示,这样就可以将底部栏隐藏了。
4、代码编程尝试
根据上面的思路,我们很容易写出如下代码:
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// 页面加载完成
hideBottom(); // 执行隐藏底部栏方法
// 隐藏底部栏方法
private void hideBottom() {
try {
//定义javaScript方法
String javascript = "javascript:function hideBottom() { "
+ "document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')[0].style.display='none'"
+ "}";
//加载方法
mWebView.loadUrl(javascript);
//执行方法
mWebView.loadUrl("javascript:hideBottom();");
} catch (Exception e) {
e.printStackTrace();
编译运行,发现底部栏并没有隐藏,但是在浏览器中我们明明是可以隐藏底部栏的,到底是哪里出了问题呢?看来只能调试了,在Android中可以打印出Js输出的日志,我们通过日志来查看程序的运行情况,在js代码中加入日志:
String javascript = "javascript:function hideBottom() { "
+ "console.log('hide bottom');" // 看方法是否执行
+ "console.log(document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed').length);" // 打印出数组的长度
+ "document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')[0].style.display='none'"
+ "}";
然后加入如下代码:
mWebView.setWebChromeClient(new WebChromeClient() {
public boolean onConsoleMessage(ConsoleMessage cm) {
Log.i("liunianprint:", "js console log: " + cm.message()); // cm.message()为js日志
return true;
打开商品详情页面,日志如下:
12-14 15:59:16.386 22315-22315/com.liunian.androidbasic I/liunianprint:: js console log: hide bottom
js console log: 0
可以看到,js方法是有被执行到的,只是通过
document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')
没有获得到页面中class为'weex-div weex-ct bpu_bottom_toolbar weex-fixed'的元素,返回的数组为空。
为什么会出现这种问题呢?我们可以看到,当日志打印出来的时候,页面其实还没有显示,所以就会导致找不到底部栏元素,也就是说在
onPageFinished调用后,其实页面还没有显示完全,导致从页面中找不到底部元素,根据我的观察,onPageFinished的调用时机一直是一个迷,并且在不同的系统版本和浏览器内核中有不同的表现,也有可能onPageFinished的调用时机是页面下载完成,并没有显示,总之,我们不能在onPageFinished中处理隐藏底部栏的操作。那么,有什么办法能够知道H5页面何时显示完成呢?我们不妨换个思路,是不是可以监听WebView的onDraw方法,onDraw方法,每当WebView需要重绘时都会调用,那么当H5页面显示完成后,肯定会调用该方法,我们可以在onDraw方法调用后在调用隐藏底部栏的方法,那样底部栏应该会隐藏,废话不多说,直接上代码:
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mOnDrawListener != null) {
mOnDrawListener.onDrawCallBack();
private OnDrawListener mOnDrawListener;
public void setOnDrawListener(OnDrawListener onDrawListener) {
mOnDrawListener = onDrawListener;
public interface OnDrawListener {
public void onDrawCallBack();
mWebView.setOnDrawListener(new MyWebView.OnDrawListener() {
@Override
public void onDrawCallBack() {
hideBottom();
运行程序,底部栏被成功隐藏掉了:
这种方式,hideBottom方法会被调用了多次,经过我的观察,对性能的影响不大,暂时不优化了。
通过这篇文章,我们可以学到以下几个方面的知识:
1、如何在Java代码中执行Js代码;
2、如何分析H5页面并准确的找到其中的某个元素;
3、如何在Java代码中调试Js代码,并成功打印出Js的log;
4、onPageFinished是不可靠的,它的调用时机不可控,为了监控H5页面的显示,我们采用了监控WebView的onDraw方法的方式。
现在前端开发中已经越来越多的使用到了H5页面,主要是因为H5页面可以及时更新、开发速度快、跨平台等特点,在Android中,我们一般使用WebView来显示H5页面,Android自带的WebView还是有很多坑的,比如内存泄露、版本的兼容、onPageFinished的调用时机等等,我们需要小心的处理这些问题。
一、说明 产品有个需求,要在App中打开天猫购物的链接,并且要隐藏掉H5页面的某些内容,让用户只能浏览商品,而不能购买,这个就需要在Java代码中操作WebView,让H5页面加载完成后能够隐藏掉某些内容。二、分析 首先我们来看一下天猫购物的链接地址:https://market.m.taobao.com/apps/market/need/yxIndex.html...
<html language="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Show And Hidden Demo</title>
什么是WebView
WebView是Android中UI组件的一种,WebView基于webkit内核,不过由于兼容性的原因在Android5.0后改为了Chromium内核。
WebView可以用来展示网页,常用于我们不想打开浏览器但又想浏览网页的情况。
WebView的使用
WebVeiw的常用方法
加载网页的四种方式
loadUrl(String url)
//打开百度网页
webView.loadUrl("https://www.baidu.com/");
//打开sdcard卡的html页
之前转载过Android webview相关的文章,Android
Webview开发问题及优化汇总,这里讲解一下实现Webview缩放以及隐藏缩放控制条所遇到的问题和坑
要支持缩放,肯定要先支持
h5加载完成时回调
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.loadUrl("javascript:" + loadJs() + ";")
fun loadJs(): String {
var js = "var newscript = document.createElement(\"script\");"
产品突然提出个需求,想去掉一个H5页面中的一段文案,避免用户点击创建新账户,如下图。这个H5页面不是我们自己写的,要不然在H5中添加一个去掉这段文案的方法,在native这边直接调用这个方法就OK了,但是这个H5页面是别人的,怎么处理呢?
webview不仅可以加载网页,同时网页的任何元素我们都是可以修改的。例如隐藏元素、替换元素、插入新的元素等等。那现在我们要做的就是:在J...
private
WebViewClient m
WebViewClient = new
WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(
WebView view, String url) {
@Override
今天接到一个需求,要求Webview在加载H5的时候需要隐藏标题。刚接到这个任务的时候第一反应是直接让前端人员删除不久行了,然后就去和产品说,经过我的据理力争,我妥协了。唉!移动端不好做啊!!!
算了,既然来需求了,那就撸起袖子干吧!
还好我们公司的前端对于标题使用的是同一个Class(没有使用id) 这样我弱小的心灵也得到了些许安慰。给前端人员点个赞。
1.首先我们要先监听页面加载完成的情况
web_common_layout.setWebViewClient(new MyWebViewCli
在使用Webview嵌入H5页面时,如何实现全屏功能呢?首先需要了解H5的全屏API是通过requestFullScreen()方法实现的,而Webview是通过WebChromeClient类的onShowCustomView和onHideCustomView方法实现的。
具体实现方法如下:
1. 首先在H5页面中添加全屏按钮,点击按钮后调用requestFullScreen()方法实现全屏。
2. 在Android中,使用WebChromeClient类中的onShowCustomView方法将H5页面全屏展示。
3. 在onShowCustomView方法中创建一个全屏的View,将H5页面的View添加到全屏View中,并将全屏View设置为Activity的ContentView。
4. 当退出全屏时,在WebChromeClient类中使用onHideCustomView方法来恢复Activity的ContentView。
总之,通过WebChromeClient类的onShowCustomView和onHideCustomView方法,我们可以实现在Android Webview中让嵌入的H5页面进行全屏显示的功能。