WebView页面嵌入原生控件

诉求:在WebView加载的web页面特定位置展示原生控件的内容,并跟随web元素滑动。

实现思路:

  1. html文档流中插入占位元素初始高度为0.
  2. 当页面加载完成后获取元素的位置,把原生控件移动到此位置.
  3. 设置占位元素高度为原生控件的高度.

效果:

黄色背景为TextView,其他为html内容

html中插入占位元素

其中id为的advertisement元素 为需要插入原生控件的的位置.

<div id="section1"></div>
<div id="advertisement"></div>
<div id="section2"></div>

获取元素的位置,移动原生控件.

这里在onPageFinished(WebView view, String url)回调中,获取元素的位置,调用js方法getAdPosition获取位置(js传回的位置单位为dp),然后通过setTranslationY移动原生控件到id为advertisement的html元素位置处.

       mWebview.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                L.e("mWebview:",mWebview.getChildCount()+"");
                TextView textView=new TextView(getApplication());
                textView.setTextColor(Color.GRAY);
                textView.setTextSize(20f);
                textView.setBackgroundColor(Color.YELLOW);
                textView.setText("WebActivity TextView ");
                textView.setGravity(Gravity.CENTER);
                textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,DensityUtil.dp2px(AndroidApplication.getContext(),TV_HEIGHT)));

                mWebview .evaluateJavascript("javaScript:getAdPosition()",
                    new ValueCallback<String>() {
                        @Override
                        public void onReceiveValue(String value) {
                            Log.i("getAdPosition:",value);
                            textView.setTranslationY(DensityUtil.dp2px(WebActivity.this,Float.parseFloat(value)));
                            mWebview.addView(textView);
                            mWebview.loadUrl("javaScript:setAdHeight("+TV_HEIGHT+")");
                        }
                    });
            }
        });

设置占位元素高度

为了避免覆盖html的内容,还需要调用js方法setAdHeightadvertisement这个div设置为和原生控件同样的高度

js中的两个方法

<script type="text/javascript">
    function getAdPosition() {
        var advertisement = document.getElementById("advertisement");
        return advertisement.offsetTop;
    }
    function setAdHeight(height) {
        var advertisement = document.getElementById("advertisement");
        advertisement.style.height=height+"px";
    }
</script>

当然如果web端不提供js方法供调用也是可以的,那就把js方法也在本地代码里定义并调用.如下:

      mWebview.evaluateJavascript("javaScript: function getAdPosition() {\n"
                            + "        var advertisement = document.getElementById(\"advertisement\");\n"
                            + "        return advertisement.offsetTop;\n"
                            + "    };getAdPosition()",
                        new ValueCallback<String>() {
                            @Override
                            public void onReceiveValue(String value) {
                                Log.i("getAdPosition:", value);
                                textView.setTranslationY(DensityUtil.dp2px(WebActivity.this, Float.parseFloat(value)));
                                mWebview.addView(textView);
                                mWebview.loadUrl("javaScript: function setAdHeight(height) {\n"
                                    + "        var advertisement = document.getElementById(\"advertisement\");\n"
                                    + "        advertisement.style.height=height+\"px\";\n"
                                    + "    };javaScript:setAdHeight("+TV_HEIGHT+");");
                            }
                        });

线上页面

以上介绍了本地html的操作方法,那么加载在线页面,或者是第三方的网站还能这样操作吗?
也是可以的,方法基本一致。

这里以百度首页为例,目的是在搜索框上面插入自己的原生组件,这里找到搜索框的id为index-form,获取位置的操作同上,
出于简单起见这里不再插入元素占位,而是直接更改搜索框的样式,当插入原生组件后修改搜索框的marginTop值。

      mWebView.evaluateJavascript("javaScript: function getAdPosition() {\n"
                              + "        var advertisement = document.getElementById(\"index-form\");\n"
                              + "        return advertisement.offsetTop;\n"
                              + "    };getAdPosition()",
                          new ValueCallback<String>() {
                              @Override
                              public void onReceiveValue(String value) {
                                  Log.e("getAdPosition:", value);
                                  textView.setTranslationY(DensityUtil.dp2px(WebActivity.this, Float.parseFloat(value)));
                                  mWebView.addView(textView);
                                  mWebView.loadUrl("javaScript: function setAdHeight(height) {\n"
                                      + "        var advertisement = document.getElementById(\"index-form\");\n"
                                      + "        advertisement.style.marginTop=height+\"px\";\n"
                                      + "    }; setAdHeight("+(TV_HEIGHT+16)+");");
                              }
                          });

获取源码:https://github.com/qkxyjren/blog/tree/master/webmix

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值