WebView 使用Android 原生ToolBar

前言

在使用 WebView 加载 H5 页面的时候,很多H5页面会有自己的标题栏,然而原生APP中也会有自己的标题栏。很多应用为保证标题栏风格与原生应用统一,或者保证返回键的使用能自由控制,选择使用原生的 ToolBar 来作为页面的标题栏。

使用原生标题栏要解决的问题

  1. 为避免出现两个标题栏,需要隐藏H5自带的标题栏;
  2. 原生标题栏需要显示 H5 标题栏中的标题

1. 隐藏H5标题栏

以一个网页为例:

http://m.ly.com/interCarTouch/view/main.html?from=groupmessage#/pickupSearch?refid=500270222

通过分析这个网页的源码,我们可以看到网页的标题栏是一个 class 名为 fed-navbar 的div,内部包含一个返回箭头和一个 h1 标题”用车“。我们要做的,就是找到这个div,并且隐藏。

如上图,在Chrome浏览器中,我们,可以通过 document.getElementsByClassName(“fed-navbar”)[0] 方法来拿到class名为 fed-navbar 的元素,并且通过设置其 style.display=”none” 来隐藏该元素。

document.getElementsByClassName("fed-navbar")[0].style.display="none"

在Android中,无法直接调试H5,但是可以在 WebViewClient 的onPageFinished方法中,插入刚才的 js 代码,来实现同样的功能:

private class MyWebViewClient extends WebViewClient {    //......    @Override    public void onPageFinished(WebView view, String url) {        super.onPageFinished(view, url);        //定义hideTitle方法,隐藏H5标题栏        String javascript =                "javascript:function hideTitle() {"                        + "var divNav = document.getElementsByClassName('fed-navbar')[0];"                        + "divNav.style.display = 'none';"                        + "}";        view.loadUrl(javascript);        // 加载hideTitle方法        view.loadUrl("javascript:hideTitle();");    }}

使用时,只需设置webView的 WebViewClient 即可:

//initViewWebView mWebView = findViewById(R.id.webview);//设置可以与JS交互mWebView.getSettings().setJavaScriptEnabled(true);//设置WebViewClientmWebView.setWebViewClient(new MyWebViewClient());mWebView.loadUrl(mUrl);

这样,隐藏标题栏就实现了。

2. 原生 ToolBar 显示H5里面的标题

这一步,我们需要做的是,从H5的内容中,取到原本的标题 “ 用车 ” ,并且设置到原生 ToolBar 中。在 WebViewClient 的 onPageFinished 方法中,我们写的 hideTitle 方法只能执行,现在我们要执行 js 方法,拿到 H5 标题,并且返回给Activity,设置到 ToolBar 上。这里我们可以使用 js 回调 java 方法,来将结果返回到 java 代码中。

  1. 先对Toolbar 初始化:

    //initView   mToolbar = findViewById(R.id.toolbar);   mToolbar.setTitle("");   setSupportActionBar(mToolbar);   mToolbar.setNavigationOnClickListener(           new View.OnClickListener() {               @Override               public void onClick(View v) {                   onBackPressed();               }           });
  2. 定义一个Java对象,来接受 js 回调的参数:

    private class InJavaScriptLocalObj {       @JavascriptInterface       public void getSource(String title) {           //拿到返回的"用车"标题           getSupportActionBar().setTitle(title);       }   }
  3. 通过 js 脚本,拿到H5标题,并在 WebViewClient 的 onPageFinished 方法中,调用 java 的 getSource 方法,传入拿到的标题

    private class MyWebViewClient extends WebViewClient {       @Override       public void onPageFinished(WebView view, String url) {           super.onPageFinished(view, url);           String javascript =                   "javascript:function hideTitle() {"                           + "var divNav = document.getElementsByClassName('fed-navbar')[0];"                           + "divNav.style.display = 'none';"                           + "}";           view.loadUrl(javascript);            // 加载hideTitle方法           view.loadUrl("javascript:hideTitle();");           //加载Java对象 InJavaScriptLocalObj 里的getSource方法,返回标题 "用车"           view.loadUrl("javascript:window.java_obj.getSource(" +                   "document.getElementsByClassName('fed-navbar-title')[0].innerHTML);");       }   }
  4. 在webView 中注册 java 对象

     //initView   mWebView = findViewById(R.id.webview);   mWebView.getSettings().setJavaScriptEnabled(true);   //注册 js 回调方法   mWebView.addJavascriptInterface(new InJavaScriptLocalObj(), "java_obj");   mWebView.setWebViewClient(new MyWebViewClient());   mWebView.loadUrl(mUrl);

完整代码如下:

public class SecondActivity extends AppCompatActivity {    public String mUrl =            "http://m.ly.com/interCarTouch/view/main.html?from=groupmessage#/pickupSearch?refid=500270222";    private WebView mWebView;    private Toolbar mToolbar;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);        // initview        mWebView = findViewById(R.id.webview);        mToolbar = findViewById(R.id.toolbar);        mToolbar.setTitle("");        setSupportActionBar(mToolbar);        mToolbar.setNavigationOnClickListener(                new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        onBackPressed();                    }                });        mWebView.getSettings().setJavaScriptEnabled(true);        mWebView.addJavascriptInterface(new InJavaScriptLocalObj(), "java_obj");        mWebView.setWebViewClient(new MyWebViewClient());        mWebView.loadUrl(mUrl);    }    private class MyWebViewClient extends WebViewClient {        @Override        public boolean shouldOverrideUrlLoading(WebView view, String url) {            view.loadUrl(url);            return true;        }        @Override        public void onPageStarted(WebView view, String url, Bitmap favicon) {            super.onPageStarted(view, url, favicon);        }        @Override        public void onPageFinished(WebView view, String url) {            super.onPageFinished(view, url);            // 同程旅游国际用车            getSupportActionBar().setTitle(view.getTitle());            String javascript =                    "javascript:function hideTitle() {"                            + "var divNav = document.getElementsByClassName('fed-navbar')[0];"                            + "divNav.style.display = 'none';"                            + "}";            view.loadUrl(javascript);            //加载Java对象 InJavaScriptLocalObj 里的getSource方法,返回标题 "用车"            view.loadUrl("javascript:window.java_obj.getSource(" +                    "document.getElementsByClassName('fed-navbar-title')[0].innerHTML);");            // 加载hideTitle方法            view.loadUrl("javascript:hideTitle();");        }    }    private class InJavaScriptLocalObj {        @JavascriptInterface        public void getSource(String title) {            //拿到返回的"用车"标题            getSupportActionBar().setTitle(title);        }    }}

在APP上效果:

更多相关文章

  1. Android原理揭秘系列之View、ViewGroup
  2. Android中AsyncTask的使用与源码分析+3.0以前的缺陷(并发->逐一)
  3. Android下使用lamemp3库将PCM录音数据压缩为MP3格式
  4. 浅谈Android中的MVP与动态代理的结合
  5. Android(安卓)设计模式第三篇:模板方法模式
  6. Android(java)学习笔记95:Android原理揭秘系列之View、ViewGroup
  7. Flutter笔记---Flutter与Android之间的相互通信MethodChannel与E
  8. Android动态模糊效果的快速实现方法
  9. 一个方便集成的 Android(安卓)右滑返回上级 控件

随机推荐

  1. 分享关于asp注册代码实例
  2. EasyLoader(简单加载)实例
  3. bootstrap-multiselect 多选实例代码
  4. 详解可选参数和命名参数实例
  5. 分享一个IoC入门教程实例
  6. [转]Composite Keys With WebApi OData
  7. 总结EF通用数据层封装类实例详解
  8. [转]Support Composite Key in ASP.NET W
  9. 学习ASP.NET Core 2遇到的问题分享
  10. 使用ConcurrentDictionary多线程同步字典