Andorid WebView中创建新窗口打开链接

需求:一个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,原来页
面的数据会再次变成初始化的数据

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值