Webview JS互动

首先要打开webview对js的支持

WebSettings settings=webView.getSettings();
settings.setJavaScriptEnabled(true);

 

这里加载assets文件里面一个网页

webView.loadUrl("file:///android_asset/webview.html");

 

在setWebChromeClient方法中重写  onJsAlert  onJsConfirm  onJsPrompt 方法来接收JS调用的 Alert  Confirm   Prompt 

 1 webView.setWebChromeClient(new WebChromeClient(){
 2             @Override
 3             public boolean onJsAlert(WebView view, String url, String message,
 4                                      final JsResult result) {
 5                 new AlertDialog.Builder(JswebActivity.this).setTitle("Alert")
 6                         .setMessage(message).setPositiveButton("确定", new DialogInterface.OnClickListener() {
 7 
 8                     @Override
 9                     public void onClick(DialogInterface dialog, int which) {
10                         result.confirm();
11                     }
12                 }).create().show();
13 
14                 return true;
15             }
16 
17             @Override
18             public boolean onJsConfirm(WebView view, String url, String message,
19                                        final JsResult result) {
20                 new AlertDialog.Builder(JswebActivity.this).setTitle("Confirm").setMessage(message)
21                         .setPositiveButton("ok", new DialogInterface.OnClickListener() {
22 
23                             @Override
24                             public void onClick(DialogInterface dialog, int which) {
25                                 result.confirm();
26                             }
27                         }).setNegativeButton("no", new DialogInterface.OnClickListener() {
28 
29                     @Override
30                     public void onClick(DialogInterface dialog, int which) {
31                         result.cancel();
32                     }
33                 }).create().show();
34 
35                 return true;
36             }
37 
38 
39             @Override
40             public boolean onJsPrompt(WebView view, String url, String message,
41                                       String defaultValue, final JsPromptResult result) {
42 
43                 final View v = View.inflate(JswebActivity.this, R.layout.prompt_dialog, null);
44                 TextView tv=(TextView) v.findViewById(R.id.prompt_message_text);
45                 tv.setText(message);
46                 ((EditText) v.findViewById(R.id.prompt_input_field)).setText(defaultValue);
47 
48                 new AlertDialog.Builder(JswebActivity.this).setTitle("Prompt").setView(v).
49                         setPositiveButton("ok", new DialogInterface.OnClickListener() {
50 
51                             @Override
52                             public void onClick(DialogInterface dialog, int which) {
53                                 String value = ((EditText) v.findViewById(R.id.prompt_input_field)).getText().toString();
54                                 result.confirm(value);
55                             }
56                         }).setNegativeButton("no", new DialogInterface.OnClickListener() {
57 
58                     @Override
59                     public void onClick(DialogInterface dialog, int which) {
60                         result.cancel();
61                     }
62                 }).create().show();
63 
64                 return true;
65             }
66         });

 

在onJsPrompt 中用到一个简单的布局  prompt_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/prompt_message_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/prompt_input_field"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minWidth="250dp"
        android:selectAllOnFocus="true"
        android:scrollHorizontally="true"/>
</LinearLayout>

 

 

在activity里面调用 网页中JS方法 

webView.loadUrl("javascript:sendText()");

JS中对应的方法

function sendText() {
        var text=android.getText();
        document.getElementById("text_msg").value=text;
    }

 

这个JS方法里面  调用了  android.getText(),这是在JS中调用activity中的方法

首先要加一个JS接口,后面加一个识别的名字,这是写的是 android 

webView.addJavascriptInterface(new JsInterface(JswebActivity.this),"android");

 

自定义接口

    public class JsInterface{
        private Context context;

        public JsInterface(Context mcontext) {
            this.context = mcontext;
        }

        @JavascriptInterface
        public void setText(String str) {
            Message message=new Message();
            message.what=1;
            message.obj=str;
            handler.sendMessage(message);

        }

        @JavascriptInterface
        public void setNum(int i) {
            Message message=new Message();
            message.what=0;
            message.obj=i;
            handler.sendMessage(message);
        }



        @JavascriptInterface
        public String getText(){
            return text;
        }

        @JavascriptInterface
        public int getNum(){
            return num;
        }

        @JavascriptInterface
        public void finish(){
            Logger.e("finish", "finish");
            JswebActivity.this.finish();
        }

        @JavascriptInterface
        public void setPrompt(String s){
            ((Button)findViewById(R.id.btn_send)).setText(s);
        }

    }

 

每个方法都要加上注解  @JavascriptInterface

这里面有一个 getText()方法,返回了 当前activity里的 text的值,JS调用 android.getText()  方法获取了activity里的 text的值

 

网页代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<input type="text" id="text_msg" value="js text">
<button type="button" onclick="submit()">提交</button>
<p></p>

<input type="number" disabled id="text_num" style="width: 30px" value="1">
<button type="button" onclick="add()">+</button>
<button type="button" onclick="reduce()">-</button>
<p></p>
===================================

<input type="text" id="text_close" value="text_">
<p></p>
<button type="button" onclick="activityclose()">close</button>
</body>

<script type="text/javascript">


    function submit() {
        var text=document.getElementById("text_msg").value;
        android.setText(text);
    }

    function add() {
        var num=document.getElementById("text_num").value;
        num++;
        document.getElementById("text_num").value=num;
        android.setNum(num);
    }

    function reduce() {
        var num=document.getElementById("text_num").value;
        num--;
        document.getElementById("text_num").value=num;
        android.setNum(num);
    }
    
    function activityclose() {
        android.finish();
    }



//-----------------------------------------------------------------------------------------------------

    function sendText() {
        var text=android.getText();
        document.getElementById("text_msg").value=text;
    }

    function sendNum() {
        document.getElementById("text_close").value="sendNum";
        var num=android.getNum()+"";
        document.getElementById("text_num").value=num;
    }
    
    function sendClose() {
        alert("This is a alert sample from html");
        document.getElementById("text_close").value="close";
        var close = window.confirm("需要关闭当前页面");
        if(close==true){
            document.getElementById("text_close").value="true close";
            android.finish();
        }else {
            document.getElementById("text_close").value="false close";
        }
    }
    
    function sendPrompt() {
        var b = prompt("please input your password","aaa");
        alert("your input is "+b);
        if (b.length>0){
            android.setPrompt(b);
        }

    }
    
    
</script>

</html>
View Code

 

 

 

微信里面加载网页的时候  顶部会有一条绿色进度条   直接ProgressBar会出现问题    最终在stackoverflow 上找到了解决方法

 

 

 布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ProgressBar
        android:id="@+id/web_bar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="-7dp"
        android:layout_marginTop="-7dp"
        android:indeterminate="false" />

</RelativeLayout>

 

逻辑代码中 红色部分是关键,颜色随便换

web_bar.getProgressDrawable().setColorFilter(Color.RED,android.graphics.PorterDuff.Mode.SRC_IN);

    // 设置加载进来的页面自适应手机屏幕
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);

        settings.setSupportZoom(true);
        settings.setBuiltInZoomControls(true);
        settings.setDisplayZoomControls(true);

 

在 setWebChromeClient 方法里 重写 onProgressChanged

            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                web_bar.setProgress(newProgress);
                if (newProgress == 100) {
                    web_bar.setVisibility(View.GONE);
                } else {
                    web_bar.setVisibility(View.VISIBLE);
                }
            }

 

 

 

webview 有不少值得注意的地方

 

其一就是千万不要 把onPageFinished 当作是网页加载完成,加载过程中,它会调用好几次。onProgressChanged 里面判断 newProgress == 100   要靠谱的多

 

退出的时候 要把webview 销毁

    @Override
    protected void onDestroy() {
        if (webView != null)
            webView.destroy();
        super.onDestroy();
    }

 

下面一种可能更好

    @Override
    protected void onDestroy() {
        if (webView!= null){
            ViewGroup viewGroup=(ViewGroup) webView.getParent();
            if (viewGroup!=null) {
                viewGroup.removeView(webView);
            }
            webView.destroy();
        }
        super.onDestroy();
    }

 

posted @ 2016-11-11 12:03  demon9  阅读(440)  评论(0编辑  收藏  举报