原来你是这样的WebView(一)

随着Html5的快速发展,越来越多的App对WebView的使用越来越频繁,不再像以前一样只需要调用webview.loadurl(url)就可以满足基本的使用,本文就对目前WebView的常用用法进行总结介绍,希望能帮到一些小伙伴…

1. WebView是个什么鬼

一个用来展示web界面的View, WebView可以在自己的浏览器或者Activity中进行内容展示,采用了WebKit渲染引擎来显示网页,包括历史导航,前一页,后一页,放大,缩小,执行搜索文本等功能;如果你想在项目中使用WebView,需要添加一个访问网络的权限:

uses-permission android:name=”android.permission.INTERNET”

2. WebView的基本使用

2.1 发送Intent调用系统浏览器打开加载页

WebView在默认情况下,不支持浏览器中例如widget插件,默认关闭Js交互,并忽略网页上将被忽略;如果你只想展示一个页面,但是并不需要交互,那使用webview是比较合适的; 如果你想实现一个全面的web页面,那么你可以开启一个URL意图来使用浏览器打开当前URL,但一般为了用户体验,这种用法的使用还是比较少的;示例如下

Uri uri = Uri.parse("http://www.baidu.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

2.2 调用webview.loadUrl(url)来加载

2.2.1 webview.loadUrl(url)加载网络地址

当然,多数情况下,我们会在layout文件中定义一个webview控件,然后在Activity中的onCreate里面加载我们想要看到的url界面,使用如下:

    //第一种写法,常用格式
    WebView webView = (WebView) findViewById(R.id.webview);
    webView.loadUrl("http://www.baidu.com");
    //注意:如果不想弹出系统浏览器进行界面显示,需要重写该方法
    webView.setWebViewClient(new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            //返回值没有关系
            return super.shouldOverrideUrlLoading(view,url);
        }
    });

    //第二种写法,直接在setContentView中传入webview
    WebView webView = new WebView(this);
    webView.loadUrl("http://www.baidu.com");
    setContentView(webView);
    webView.setWebViewClient(new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            //返回值没有关系
            return super.shouldOverrideUrlLoading(view,url);
        }
    });

注意:如果不想弹出系统浏览器进行界面显示,需要重写shouldOverrideUrlLoading方法

2.2.2 webview.loadUrl(url)加载apk包内html文件

webview不但可以加载网络页面,也可以加载apk包下的html文件,将html文件放在项目assets资源目录下,然后调用以下代码即可

webView.loadUrl("file:///android_asset/test.html");
2.2.3 webview.loadUrl(url)加载SD卡下的html文件

webview加载SD卡根目录下test.html文件代码如下:

webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");

2.3 webview加载HTML格式字符串

除了可以加载网页之外,webview也可以加载HTML格式的字符串;主要是两个方法,一个webView.loadData(data,mimeType,encoding);来展示,一个是webView.loadDataWithBaseURL(baseUrl,data,mimeType,encoding,historyUrl);. 如果是带有中文的数据,默认显示会展示乱码,可以有两种方式来解决乱码;我们先来看一下如果都是英文数据该如何展示:

String data = "<html><body>You scored <b>Egglish</b> points.</body></html>";
webView.loadData(summary, "text/html", null);

展示效果如图所示:

如果包含了中文,会显示乱码:

第一种修改方式,可以在loadData中更改第二个参数,注意:如果将第三个参数更改为”UTF-8”,依然会是乱码;正确修改如下:

String data = "<html><body>You scored <b>中文测试</b> points.</body></html>";
webView.loadData(data, "text/html; charset=UTF-8", null);

显示效果如下:

原因如下:

如果用 loadDataWithBaseURL时,如果不传入URL时,刷新会造成白屏,因为刷新时调用的的是reload方法,reload是根据传入的URL进行一次重新加载即再次loadUrl(url),不传入URL时,默认的的URL是about:blank;使用loadData,刷新只是从缓存里面取,但是在4.0以上的,如果按照API里所写的loadData(data, “UTF-8”, null);时会乱码,如果写成loadData(data, "text/html; charset=UTF-8", null);loadData最终的机制是会把传入的三个参数拼接在一起,然后再进行loadUrl操作,参数就是data, "text/html; charset=UTF-8", null这三个进行拼装,加入text/html; charset=UTF-8就相当于限定了页面的字符

上面的一种修改方式可以适配大多数机型,但依然有少部分机型会显示乱码,可能与系统底层文件修改有关,所以就有了另一种修改方式,调用loadDataWithBaseURL方法,修改如下:

String data = "<html><body>You scored <b>中文测试</b> points.</body></html>";
webView.loadDataWithBaseURL(null,summary,"text/html","UTF-8",null);

3. 自定义你的webview

WebView除了基本的用法以外,还可以进行自定义来达到你想要的效果,比如创建一个匿名WebChromeClient来辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等;也可以创建一个匿名WebViewClient ,来帮助WebView处理各种通知、请求事件等;当然,也可以启用 WebSettings,来开启Js交互等等,下面我们就来逐一介绍.

3.1 WebChromeClient

方法中的代码均有Android端自行处理,实现方式可以写一个匿名内部类,或者写一个WebChromeClient类,然后调用webview.setWebChromeClient(mWebChromeClient);代码示例如下:

webView.setWebChromeClient(new WebChromeClient() {
    //获取网页的加载进度,因有的网页是采用分模块加载,所以进度值并非只是一次1~100;可以为: 29~100;30~100;
    @Override
    public void onProgressChanged(WebView view, int progress) {
        Log.e(TAG,"progress="+progress);
    }

    //获取当前网页中的Title值来设置给自己的title
    //注意:如果无网,获取的 title= 找不到网页
    //所以开发者可以在接受到onReceiveError的回调后,不要在使用当前获取的title值了
    @Override
    public void onReceivedTitle(WebView view, String title) {
        Log.e(TAG,"title="+title);
    }
    //获取当前网页的icon,拿到后,会获取一个Bitmap对象,你想干嘛就干嘛
    @Override
    public void onReceivedIcon(WebView view, Bitmap icon) {
        super.onReceivedIcon(view, icon);
    }

});

以上为简单用法,下面我们对 onJsAlert(), onJsPrompt(),onJsConfirm()进行逐一分析;在WebChromeClient类里可以重写这三个方法,此时WebView中加载的html中如果执行alert("alert...."); , confirm("confirm..."); , prompt("prompt...", "defaultValue");这三个方法,该类就会监听到执行对应的三个方法。我们可以让这三个方法的返回值为true ,即自定义此方法。在里面写入自己定义的Dialog,便可实现html与Activity交互。

注意 JsResult 此类需要在操作时,如果操作则 result.cofirm(). 取消则 result.cancel(); 还必须这每一个方法中写入 dialog.setOnkeyListener(); 方法来监听Back键,listener中    要写 result.cancel(); 否则系统没有消费这个事件,会出错。

3.1.1 自定义onJsAlert

什么是Javascript Alert?

Alert是一种提示信息或者警告信息的对话框,一旦显示到用户面前,只能点击OK才能关闭.

通常一般的实现类似:

<html>
   <SCRIPT type="text/javascript">
       alert('This is alert dialog !')
   </SCRIPT>
</html>

效果图如下:

onJsAlert API 介绍:

public boolean onJsAlert (WebView view, String url, String message, JsResult result)

Tell the client to display a javascript alert dialog. If the client returns true, WebView will assume that the client will handle the dialog. If the client returns false, it will continue execution.

告知客户端将显示一个alert dialog; 如果方法返回了true, 那么webview就会来自行处理这个dialog; 如果返回了false,则会继续执行下去,webview不进行处理;

在Android中,我们一般重写onJsAlert方法,会将参数中的message信息用Toast的形式弹出以告知用户,代码如下;

@Override
   public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
       Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
       因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。
       result.confirm();
       return true;
   }

或者我们可以自行弹出一个Dialog,覆盖默认的显示界面,代码如下:

@Override
   public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
       final AlertDialog.Builder builder = new AlertDialog.Builder(view
               .getContext());
       builder.setTitle("测试自定义对话框").setMessage(message)
               .setPositiveButton("确定", null);
       //这里不需要绑定按键事件
       //可自行屏蔽keycode按键
       builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
           @Override
           public boolean onKey(DialogInterface dialog, int keyCode,
                                KeyEvent event) {
               Log.e(TAG,"keyCode==" + keyCode + "event=" + event);
               return true;
           }
       });
       //禁止响应按back键的事件
       builder.setCancelable(false);
       AlertDialog dialog = builder.create();
       dialog.show();
       result.confirm();//因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。
       return true;
   }
3.1.2 自定义onJsConfirm

用法与onJsAlert基本一样,直接上代码:

@Override
   public boolean onJsConfirm(WebView view, String url, String message,
                              final JsResult result) {
       final AlertDialog.Builder builder = new AlertDialog.Builder(view
               .getContext());
       builder.setTitle("webview测试confirm对话框")
               .setMessage(message)
               .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                   @Override
                   public void onClick(DialogInterface dialog, int which) {
                       result.confirm();
                   }
               })
               .setNeutralButton("取消", new DialogInterface.OnClickListener() {
                   @Override
                   public void onClick(DialogInterface dialog, int which) {
                       result.cancel();
                   }
       });
       builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
           @Override
           public void onCancel(DialogInterface dialog) {
               result.cancel();
           }
       });

       //屏蔽keycode的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
       builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
           @Override
           public boolean onKey(DialogInterface dialog, int keyCode,
                                KeyEvent event) {
               Log.e(TAG, "keyCode==" + keyCode + "event=" + event);
               return true;
           }
       });
       //禁止响应按back键的事件
       builder.setCancelable(false);
       AlertDialog dialog = builder.create();
       dialog.show();
       return true;
   }
3.1.3 自定义 onJsPrompt

直接上代码,大致用法一样,只不过个别参数不同:

@Override
   public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
       final AlertDialog.Builder builder = new AlertDialog.Builder(view
               .getContext());
       builder.setTitle("webview测试prompt对话框").setMessage(message);

       final EditText et = new EditText(view.getContext());
       et.setSingleLine();
       et.setText(defaultValue);
       builder.setView(et);
       builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
               result.confirm(et.getText().toString());
           }
       }).setNeutralButton("取消", new DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
               result.cancel();
           }
       });

       //屏蔽keycode按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
       builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
           @Override
           public boolean onKey(DialogInterface dialog, int keyCode,
                                KeyEvent event) {
               Log.e(TAG, "keyCode==" + keyCode + "event=" + event);
               return true;
           }
       });

       //禁止响应按back键的事件
       builder.setCancelable(false);
       AlertDialog dialog = builder.create();
       dialog.show();
       return true;
   }

4. 使用websettings让你的webview更加强大

webview获取到websettings之后,可以对当前的webview进行各种设置,如 Js交互开启,缩放,支持插件等等,我们直接以代码为例,代码中对每个功能点都进行了详细说明,请小伙伴参阅;

WebSettings webSettings = webView.getSettings();

   //支持获取手势焦点,输入用户名、密码或其他
   webView.requestFocusFromTouch();
   //支持js交互
   webSettings.setJavaScriptEnabled(true);
   webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口

   //设置自适应屏幕,需要与setLoadWithOverviewMode合用
   webSettings.setUseWideViewPort(true);  //可以将图片调整到适合webview的大小
   webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

   //支持缩放,默认为true。是setBuiltInZoomControls的前提。
   //若setSupportZoom是false,则该WebView不可缩放,这个不管setBuiltInZoomControls设置什么都不能缩放。
   webSettings.setSupportZoom(true);
   webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件

   webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

   //提高渲染的优先级
   webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);

   webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持内容重新布局
   webSettings.supportMultipleWindows();  //支持多窗口
   webSettings.setAllowFileAccess(true);  //设置可以访问文件
   webSettings.setLoadsImagesAutomatically(true);  //支持自动加载图片
   webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式

好了,上面就是webview的一些简单用法,后面我们将对webview的缓存机制,前进回退操作,与js互调,避免webview内存泄露等问题进行逐一分析,希望我的文字能在你需要的时候帮到你, 愿大家有美好的一天…..

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值