需求:一个Activity内嵌的WebView,WebView已加载一个页面,在加载的页面中有一个超链接,可点击跳转到新的页面;
要求:跳转至新页面需要像浏览器一样创建新窗口展示,也即是新标签,多窗口样式,不能调用外部浏览器,且通过手机返回键返回时,关闭新打开的标签,不影响原来的页面显示
实现方式为新建一个webveiw用来加载新的链接地址
一、.MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "xuwei";
private WebView webview;
private WebView newWebView;
private Button btn_close;
private RelativeLayout rl_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_close = findViewById(R.id.btn_close);
webview = findViewById(R.id.webview);
rl_main = findViewById(R.id.rl_main);
btn_close.setOnClickListener(this);
initWebView();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_close:
if (webview.canGoBack()) {
webview.goBack();// 返回前一个页面
Log.d(TAG, "onKeyDown: 原来的webview回退");
}
if (newWebView.canGoBack()) {
newWebView.goBack();// 返回前一个页面
Log.d(TAG, "onKeyDown: 新建的webview回退");
} else if (newWebView != null) {
Log.d(TAG, "onKeyDown: webview 为空,销毁");
rl_main.removeView(newWebView);
newWebView.destroy();
newWebView = null;
}
break;
}
}
private void initWebView() {
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);//设置支持javaScript脚步语言
webSettings.setSupportMultipleWindows(true);//支持打开多窗口
webview.setWebViewClient(new MyWebview());
webview.setWebChromeClient(new MyWebClient());
webview.addJavascriptInterface(new AndroidAndJSInterface(), "Android"); //设置支持js调用java
//加载网络资源
webview.loadUrl("file:///android_asset/JavaAndJavaScriptCall.html");
}
/**
* js可以调用该类的方法
*/
class AndroidAndJSInterface {
@JavascriptInterface
public void showAndroid() {
Toast.makeText(MainActivity.this, "Android代码!", Toast.LENGTH_SHORT).show();
runOnUiThread(new Runnable() {
@Override
public void run() {
webview.loadUrl("javascript:javaCallJs(" + "'" + "Activity与js交互的数据" + "'" + ")");
}
});
}
}
private class MyWebview extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
Log.d(TAG, "onPageFinished: url:" + url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.d(TAG, "不在新窗口,直接加载: url:" + url);
view.loadUrl(url);
return true;
}
}
private class MyWebClient extends WebChromeClient {
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
newWebView = new WebView(MainActivity.this);
WebSettings settings = newWebView.getSettings();
settings.setJavaScriptEnabled(true);//支持js
rl_main.addView(newWebView);
newWebView.setWebViewClient(new WebViewClient());
newWebView.setWebChromeClient(this);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newWebView);
resultMsg.sendToTarget();
Log.d(TAG, "onCreateWindow: 新标签中打开网页");
return true;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (webview.canGoBack()) {
webview.goBack();// 返回前一个页面
Log.d(TAG, "onKeyDown: 原来的webview回退");
return true;
}
if (newWebView.canGoBack()) {
newWebView.goBack();// 返回前一个页面
Log.d(TAG, "onKeyDown: 新建的webview回退");
return true;
} else if (newWebView != null) {
Log.d(TAG, "onKeyDown: webview 为空,销毁");
rl_main.removeView(newWebView);
newWebView.destroy();
newWebView = null;
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<WebView
android:id="@+id/webview"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/btn_close"
android:text="关闭"
android:background="@color/gray"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
二、.放置在assets目录下的JavaAndJavaScriptCall.html文件,初始加载页面
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script type="text/javascript">
function AndoridToJs(){
document.getElementById("content").innerHTML +=
"<br\>这是JavaScript的无参构造函数";
}
function javacalljs(){
document.getElementById("content").innerHTML +=
"<br\>java调用了js无参函数";
}
function javaCallJs(arg){
document.getElementById("content").innerHTML =
(arg );
}
function showDialog(){
alert("你好,我是来自javascript");
}
</script>
</head>
<br>
<div align="left" id="content">test</div>
<!--<div align="right">标题</div>-->
<!--<p><img src="http://atguigu.com/images/logo.gif"></p>-->
<!--<p><img src="http://img5.imgtn.bdimg.com/it/u=1219331396,194612919&fm=26&gp=0.jpg" width="350" height="350"></p>-->
<br></br>
<input type="button" value="js与Android交互" onclick="window.Android.showAndroid()"/>
<br></br>
<a href="http://www.baidu.com" target="_blank">百度一下,_blank新窗口打开</a>
<br></br>
<a href="https://cn.bing.com/" >必应搜索,webview直接加载</a>
</body>
</html>
三、.重点关注点:
1.打开超链接时有属性target="_blank",支持打开多窗口
webSettings.setSupportMultipleWindows(true);
webview.setWebViewClient(new WebViewClient());
在WebViewClient重写onCreateWindow
2.超链接没有属性target="_blank",则会用同一个webview加载
webview.setWebViewClient(new MyWebview());3.返回时回退键的处理,onKeyDown,测试时打开新窗口时返回时原来页面不受影响,不是用新窗口打开的则会重新加载webview,原来页
面的数据会再次变成初始化的数据
本文详细介绍了如何在Android应用中使用WebView实现多窗口浏览功能,包括设置WebView支持多窗口、处理超链接在新窗口打开、以及自定义WebViewClient和WebChromeClient来控制页面加载和窗口切换。
768

被折叠的 条评论
为什么被折叠?



