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



    
    

 

二、.放置在assets目录下的JavaAndJavaScriptCall.html文件,初始加载页面


    
        
        

    

    
test




百度一下,_blank新窗口打开

必应搜索,webview直接加载

三、.重点关注点:

1.打开超链接时有属性target="_blank",支持打开多窗口

webSettings.setSupportMultipleWindows(true);

webview.setWebViewClient(new WebViewClient());

在WebViewClient重写onCreateWindow

2.超链接没有属性target="_blank",则会用同一个webview加载

webview.setWebViewClient(new MyWebview());3.返回时回退键的处理,onKeyDown,测试时打开新窗口时返回时原来页面不受影响,不是用新窗口打开的则会重新加载webview,原来页
面的数据会再次变成初始化的数据

 

你可能感兴趣的:(Android)