WebView 使用Android(安卓)原生ToolBar
WebView 使用Android 原生ToolBar
前言
在使用 WebView 加载 H5 页面的时候,很多H5页面会有自己的标题栏,然而原生APP中也会有自己的标题栏。很多应用为保证标题栏风格与原生应用统一,或者保证返回键的使用能自由控制,选择使用原生的 ToolBar 来作为页面的标题栏。
使用原生标题栏要解决的问题
- 为避免出现两个标题栏,需要隐藏H5自带的标题栏;
- 原生标题栏需要显示 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 代码中。
先对Toolbar 初始化:
//initView mToolbar = findViewById(R.id.toolbar); mToolbar.setTitle(""); setSupportActionBar(mToolbar); mToolbar.setNavigationOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } });
定义一个Java对象,来接受 js 回调的参数:
private class InJavaScriptLocalObj { @JavascriptInterface public void getSource(String title) { //拿到返回的"用车"标题 getSupportActionBar().setTitle(title); } }
通过 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);"); } }
在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上效果:
更多相关文章
- Android原理揭秘系列之View、ViewGroup
- Android中AsyncTask的使用与源码分析+3.0以前的缺陷(并发->逐一)
- Android下使用lamemp3库将PCM录音数据压缩为MP3格式
- 浅谈Android中的MVP与动态代理的结合
- Android(安卓)设计模式第三篇:模板方法模式
- Android(java)学习笔记95:Android原理揭秘系列之View、ViewGroup
- Flutter笔记---Flutter与Android之间的相互通信MethodChannel与E
- Android动态模糊效果的快速实现方法
- 一个方便集成的 Android(安卓)右滑返回上级 控件