在智能移动设备上打开浏览器浏览网页是移动用户很经常的操作。本文就来讲解Android中一个可以进行网页显示的控件WebView。同Chrome和Safari一样,WebView的网页渲染引擎也是Webkit。

       使用WebView控件进行Android互联网程序开发又如下优势: 

       1、可以打开远程网址、也可以加载本地Html数据。

       2、可以搭建Java和Javascript交互桥梁。

       3、WebView控件可以高度定制。

       下面我们通过几个例子来共同学习WebView的使用方法。

       一、先做一个例子热热身看看效果:通过WebView访问一个网站

       1、先来一个简单的例子,新建一个项目Lesson29_WebView。

       2、因为要访问互联网所以先在AndroidManifest.xml中设定权限:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.basic.lesson29" android:versioncode="1" android:versionname="1.0">  
  3.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  4.         <activity android:label="@string/app_name" android:name=".MainWebView">  
  5.             <intent -filter="">  
  6.                 <action android:name="android.intent.action.MAIN">  
  7.                 <category android:name="android.intent.category.LAUNCHER">  
  8.             </category></action></intent>  
  9.         </activity>  
  10.   
  11.     </application>  
  12.     <uses -sdk="" android:minsdkversion="8">  
  13.     <uses -permission="" android:name="android.permission.INTERNET">  
  14. </uses></uses></manifest>   

       3、在res/layout/main.xml中放置一个输入框,一个按钮和一个WebView:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#fff">  
  3. </linearlayout>  
  4. <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content">  
  5.     <edittext android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="http://android.yaohuiji.com" android:id="@+id/EditText01" android:layout_weight="1">  
  6.     </edittext>  
  7.     <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Go" android:id="@+id/Button01" android:layout_weight="0">  
  8.     </button>  
  9. </linearlayout>  
  10.   
  11. <webview android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#fff" android:id="@+id/WebView01">  
  12. </webview>  

       4、在Activity文件的OnCreate方法中默认载入一个百度页面,点击按钮时载入预设的网址:

Java代码
  1. package android.basic.lesson29;   
  2.   
  3. import android.app.Activity;   
  4. import android.os.Bundle;   
  5. import android.view.View;   
  6. import android.webkit.WebView;   
  7. import android.widget.Button;   
  8. import android.widget.EditText;   
  9.   
  10. public class MainWebView extends Activity {   
  11.   
  12.     WebView mWebView;   
  13.   
  14.     /** Called when the activity is first created. */  
  15.     @Override  
  16.     public void onCreate(Bundle savedInstanceState) {   
  17.         super.onCreate(savedInstanceState);   
  18.         setContentView(R.layout.main);   
  19.   
  20.         //定义UI组件   
  21.         mWebView = (WebView) findViewById(R.id.WebView01);   
  22.         Button b1 = (Button) findViewById(R.id.Button01);   
  23.         final EditText et = (EditText) findViewById(R.id.EditText01);   
  24.   
  25.         //得到WebSetting对象,设置支持Javascript的参数   
  26.         mWebView.getSettings().setJavaScriptEnabled(true);   
  27.         //载入URL   
  28.         mWebView.loadUrl("http://www.baidu.com");   
  29.         //使页面获得焦点   
  30.         mWebView.requestFocus();   
  31.   
  32.         //给按钮绑定单击监听器   
  33.         b1.setOnClickListener(new View.OnClickListener() {   
  34.   
  35.             @Override  
  36.             public void onClick(View v) {   
  37.                 //访问编辑框中的网址   
  38.                 mWebView.loadUrl(et.getText().toString());   
  39.             }   
  40.         });   
  41.   
  42.     }   
  43. }  

       运行程序,在编辑框中输入一个网址,点击Go按钮,就可以看到该网页显示,不过没有经过任何缩放处理,在接下里的例子我们继续研究,如何做更多的控制。

       二、WebSettings基础知识补充

       1、先看一下WebView的继承关系,可以看到它不是在android.widget包中,而是在android.webkit包中。

 Android学习指南之二十九:WebView使用详解

       2、WebSettings :WebView组件有一个辅助类叫WebSettings,它管理WebView的设置状态。该对象可以通过WebView.getSettings()方法获得。下面举几个例子来说明WebSettings的用法:

Java代码
  1. //得到WebSettings对象,设置支持Javascript的参数   
  2.   
  3. mWebView.getSettings().setJavaScriptEnabled(true);   
  4.   
  5. //设置可以支持缩放   
  6.   
  7. mWebView.getSettings().setSupportZoom(true);   
  8.   
  9. //设置默认缩放方式尺寸是far   
  10.   
  11. mWebView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);   
  12.   
  13. //设置出现缩放工具   
  14.   
  15. mWebView.getSettings().setBuiltInZoomControls(true);  

       三、加载assets目录下的本地网页

       WebView调用assets目录下的本地网页和图片等资源非常方便,使用形如:

       wv.loadUrl("file:///android_asset/html/test1.html");

       的调用方法即可,代码在第四段落里。

 Android学习指南之二十九:WebView使用详解

       在test1中点击链接也可以跳转到test2。

 Android学习指南之二十九:WebView使用详解

       四、使用LoadData方法加载内容

       可以在Java文件中或者XML文件中定义HTML的片段,也可以在assets目录中存放HTML文件,然后使用LoadData加载其中的内容,展示出来。下面我们使用第三部分的网页来演示一下如何使用LoadData方法,并且看看他们之间的区别。

       1、新建项目Lesson29_WebView2

       2、新建2个Html文件在assets/html下,内容略去,res/layout/main.xml的内容也略去了,相信对你来说已经不成问题。

       3、MainWebView2.java 的内容如下:

Java代码
  1. package android.basic.lesson29;   
  2.   
  3. import java.io.IOException;   
  4. import java.io.InputStream;   
  5.   
  6. import org.apache.http.util.ByteArrayBuffer;   
  7. import org.apache.http.util.EncodingUtils;   
  8.   
  9. import android.app.Activity;   
  10. import android.os.Bundle;   
  11. import android.view.View;   
  12. import android.webkit.WebView;   
  13. import android.widget.Button;   
  14.   
  15. public class MainWebView2 extends Activity {   
  16.     /** Called when the activity is first created. */  
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {   
  19.         super.onCreate(savedInstanceState);   
  20.         setContentView(R.layout.main);   
  21.   
  22.         //定义UI组件   
  23.         Button b1 = (Button) findViewById(R.id.Button01);   
  24.         Button b2 = (Button) findViewById(R.id.Button02);   
  25.   
  26.         final WebView wv = (WebView) findViewById(R.id.WebView01);   
  27.   
  28.         //定义并绑定按钮单击监听器   
  29.         b1.setOnClickListener(new View.OnClickListener() {   
  30.             @Override  
  31.             public void onClick(View v) {   
  32.                 //加载URL assets目录下的内容可以用 "file:///android_asset" 前缀   
  33.                 wv.loadUrl("file:///android_asset/html/test1.html");   
  34.             }   
  35.         });   
  36.   
  37.         //定义并绑定按钮单击监听器   
  38.         b2.setOnClickListener(new View.OnClickListener() {   
  39.             @Override  
  40.             public void onClick(View v) {   
  41.                 String data = "";   
  42.                 try {   
  43.                     // 读取assets目录下的文件需要用到AssetManager对象的Open方法打开文件   
  44.                     InputStream is = getAssets().open("html/test2.html");   
  45.                     // loadData()方法需要的是一个字符串数据所以我们需要把文件转成字符串   
  46.                     ByteArrayBuffer baf = new ByteArrayBuffer(500);   
  47.                     int count = 0;   
  48.                     while ((count = is.read()) != -1) {   
  49.                         baf.append(count);   
  50.                     }   
  51.                     data = EncodingUtils.getString(baf.toByteArray(), "utf-8");   
  52.                 } catch (IOException e) {   
  53.                     e.printStackTrace();   
  54.                 }   
  55.                 // 下面两种方法都可以加载成功   
  56.                 wv.loadData(data, "text/html""utf-8");   
  57.                 // wv.loadDataWithBaseURL("", data, "text/html", "utf-8", "");   
  58.             }   
  59.         });   
  60.   
  61.     }   
  62. }  

       4、运行程序单击第二个按钮,效果如下:

 Android学习指南之二十九:WebView使用详解

       对比上面的例子,我们可以看到两个明显的区别,其一,图片没加载出来,其二链接失效,点击后无法加载test1.html 。

       五、两个和WebView相关的重要对象:WebChromeClient和WebViewClient

       和WebView相关的辅助对象,除了WebSettings以外还有WebChromeClient和WebViewClient。

       接下来的这个例子内容比较丰富,虽然注释比较清晰,但是您一次消化起来还是比较困难的,因此您需要的是一点点耐心,多看几遍,最重要的是自己至少敲代码敲一遍。

       1、在上面的例子中继续增加内容,增加test3.html的内容:

XML/HTML代码
  1.   
  2.      <script type="text/JavaScript">        
  3.      function alertFuction(){    
  4.        var a=1;   
  5.        var b=2    
  6.        alert(a+b);         
  7.      }     
  8.      function confirmFuction(){     
  9.         confirm("你确定要删除吗?")     
  10.      }     
  11.   
  12.      </script>      
  13.   
  14. 对话框测试   
  15. <input onclick="alertFuction()" value="提醒对话框" type="button">  
  16. <input onclick="confirmFuction()" value="选择对话框" type="button">  
  17.   
  18.    <a href="test1.html">上一页</a>  

       2、MainWebView3.java的内容,请注意注释内容:

Java代码
  1. package android.basic.lesson29;   
  2.   
  3. import java.io.FileOutputStream;   
  4.   
  5. import android.app.Activity;   
  6. import android.app.AlertDialog;   
  7. import android.app.AlertDialog.Builder;   
  8. import android.content.DialogInterface;   
  9. import android.graphics.Bitmap;   
  10. import android.graphics.Canvas;   
  11. import android.graphics.Picture;   
  12. import android.os.Bundle;   
  13. import android.view.KeyEvent;   
  14. import android.view.View;   
  15. import android.webkit.JsPromptResult;   
  16. import android.webkit.JsResult;   
  17. import android.webkit.WebChromeClient;   
  18. import android.webkit.WebView;   
  19. import android.webkit.WebViewClient;   
  20. import android.widget.Button;   
  21. import android.widget.Toast;   
  22.   
  23. public class MainWebView3 extends Activity {   
  24.   
  25.     /** Called when the activity is first created. */  
  26.     @Override  
  27.     public void onCreate(Bundle savedInstanceState) {   
  28.         super.onCreate(savedInstanceState);   
  29.         setContentView(R.layout.main);   
  30.   
  31.         // 定义UI组件   
  32.         Button b1 = (Button) findViewById(R.id.Button01);   
  33.         Button b2 = (Button) findViewById(R.id.Button02);   
  34.         Button b3 = (Button) findViewById(R.id.Button03);   
  35.   
  36.         final WebView wv = (WebView) findViewById(R.id.WebView01);   
  37.   
  38.         // 覆盖默认后退按钮的作用,替换成WebView里的查看历史页面   
  39.         wv.setOnKeyListener(new View.OnKeyListener() {   
  40.   
  41.             @Override  
  42.             public boolean onKey(View v, int keyCode, KeyEvent event) {   
  43.                 if (event.getAction() == KeyEvent.ACTION_DOWN) {   
  44.                     if ((keyCode == KeyEvent.KEYCODE_BACK) && wv.canGoBack()) {   
  45.                         wv.goBack();   
  46.                         return true;   
  47.                     }   
  48.                 }   
  49.                 return false;   
  50.             }   
  51.         });   
  52.   
  53.         // 设置支持Javascript   
  54.         wv.getSettings().setJavaScriptEnabled(true);   
  55.   
  56.         // 定义并绑定按钮单击监听器   
  57.         b1.setOnClickListener(new View.OnClickListener() {   
  58.             @Override  
  59.             public void onClick(View v) {   
  60.                 // 加载URL assets目录下的内容可以用 "file:///android_asset" 前缀   
  61.                 wv.loadUrl("file:///android_asset/html/test1.html");   
  62.             }   
  63.         });   
  64.   
  65.         // 定义并绑定按钮单击监听器   
  66.         b2.setOnClickListener(new View.OnClickListener() {   
  67.             @Override  
  68.             public void onClick(View v) {   
  69.                 // 加载URL assets目录下的内容可以用 "file:///android_asset" 前缀   
  70.                 wv.loadUrl("file:///android_asset/html/test3.html");   
  71.             }   
  72.         });   
  73.   
  74.         // 定义并绑定按钮单击监听器   
  75.         b3.setOnClickListener(new View.OnClickListener() {   
  76.             @Override  
  77.             public void onClick(View v) {   
  78.                 Picture pic = wv.capturePicture();   
  79.                 int width = pic.getWidth();   
  80.                 int height = pic.getHeight();   
  81.                 if (width > 0 && height > 0) {   
  82.                     Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);   
  83.                     Canvas canvas = new Canvas(bmp);   
  84.                     pic.draw(canvas);   
  85.                     try {   
  86.                         String fileName = "sdcard/" + System.currentTimeMillis() + ".png";   
  87.                         FileOutputStream fos = new FileOutputStream(fileName);   
  88.   
  89.                         if (fos != null) {   
  90.                             bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);   
  91.                             fos.close();   
  92.                         }   
  93.                         Toast.makeText(getApplicationContext(), "截图成功,文件名是:" + fileName, Toast.LENGTH_SHORT).show();   
  94.                     } catch (Exception e) {   
  95.                         e.printStackTrace();   
  96.                     }   
  97.                 }   
  98.             }   
  99.         });   
  100.   
  101.         // 创建WebViewClient对象   
  102.         WebViewClient wvc = new WebViewClient() {   
  103.   
  104.             @Override  
  105.             public boolean shouldOverrideUrlLoading(WebView view, String url) {   
  106.                 Toast.makeText(getApplicationContext(), "WebViewClient.shouldOverrideUrlLoading", Toast.LENGTH_SHORT)   
  107.                         .show();   
  108.                 // 使用自己的WebView组件来响应Url加载事件,而不是使用默认浏览器器加载页面   
  109.                 wv.loadUrl(url);   
  110.                 // 记得消耗掉这个事件。给不知道的朋友再解释一下,Android中返回True的意思就是到此为止吧,事件就会不会冒泡传递了,我们称之为消耗掉   
  111.                 return true;   
  112.             }   
  113.   
  114.             @Override  
  115.             public void onPageStarted(WebView view, String url, Bitmap favicon) {   
  116.                 Toast.makeText(getApplicationContext(), "WebViewClient.onPageStarted", Toast.LENGTH_SHORT).show();   
  117.                 super.onPageStarted(view, url, favicon);   
  118.             }   
  119.   
  120.             @Override  
  121.             public void onPageFinished(WebView view, String url) {   
  122.                 Toast.makeText(getApplicationContext(), "WebViewClient.onPageFinished", Toast.LENGTH_SHORT).show();   
  123.                 super.onPageFinished(view, url);   
  124.             }   
  125.   
  126.             @Override  
  127.             public void onLoadResource(WebView view, String url) {   
  128.                 Toast.makeText(getApplicationContext(), "WebViewClient.onLoadResource", Toast.LENGTH_SHORT).show();   
  129.                 super.onLoadResource(view, url);   
  130.             }   
  131.   
  132.         };   
  133.   
  134.         // 设置WebViewClient对象   
  135.         wv.setWebViewClient(wvc);   
  136.   
  137.         // 创建WebViewChromeClient   
  138.         WebChromeClient wvcc = new WebChromeClient() {   
  139.   
  140.             // 处理Alert事件   
  141.             @Override  
  142.             public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {   
  143.                 // 构建一个Builder来显示网页中的alert对话框   
  144.                 Builder builder = new Builder(MainWebView3.this);   
  145.                 builder.setTitle("计算1+2的值");   
  146.                 builder.setMessage(message);   
  147.                 builder.setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() {   
  148.                     @Override  
  149.                     public void onClick(DialogInterface dialog, int which) {   
  150.                         result.confirm();   
  151.                     }   
  152.                 });   
  153.                 builder.setCancelable(false);   
  154.                 builder.create();   
  155.                 builder.show();   
  156.                 return true;   
  157.             }   
  158.   
  159.             @Override  
  160.             public void onReceivedTitle(WebView view, String title) {   
  161.                 MainWebView3.this.setTitle("可以用onReceivedTitle()方法修改网页标题");   
  162.                 super.onReceivedTitle(view, title);   
  163.             }   
  164.   
  165.             // 处理Confirm事件   
  166.             @Override  
  167.             public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {   
  168.                 Builder builder = new Builder(MainWebView3.this);   
  169.                 builder.setTitle("删除确认");   
  170.                 builder.setMessage(message);   
  171.                 builder.setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener() {   
  172.   
  173.                     @Override  
  174.                     public void onClick(DialogInterface dialog, int which) {   
  175.                         result.confirm();   
  176.                     }   
  177.   
  178.                 });   
  179.                 builder.setNeutralButton(android.R.string.cancel, new AlertDialog.OnClickListener() {   
  180.   
  181.                     @Override  
  182.                     public void onClick(DialogInterface dialog, int which) {   
  183.                         result.cancel();   
  184.                     }   
  185.   
  186.                 });   
  187.                 builder.setCancelable(false);   
  188.                 builder.create();   
  189.                 builder.show();   
  190.                 return true;   
  191.             }   
  192.   
  193.             // 处理提示事件   
  194.             @Override  
  195.             public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,   
  196.                     JsPromptResult result) {   
  197.                 // 看看默认的效果   
  198.                 return super.onJsPrompt(view, url, message, defaultValue, result);   
  199.             }   
  200.         };   
  201.   
  202.         // 设置setWebChromeClient对象   
  203.         wv.setWebChromeClient(wvcc);   
  204.     }   
  205. }  

       3、运行程序,查看结果:

 Android学习指南之二十九:WebView使用详解

       启动起来时的画面:

 Android学习指南之二十九:WebView使用详解

       点击第一个按钮,我们可以看到WebViewClient对象中定义的方法的确被调用了。

Android学习指南之二十九:WebView使用详解

       点击第二个按钮,我们看到加载的网页中有两个按钮,我们知道默认情况下Android会直接忽略掉由javascript弄出来的alert等弹出信息,除非我们在WebChromeClient中覆盖onJsAlert()方法和onJsConfirm()方法,让我们分别点击它们看看效果。

 Android学习指南之二十九:WebView使用详解

Android学习指南之二十九:WebView使用详解 

       接下来我们再页面中跳转几次后,使用后退按钮,查看我们是否屏蔽了Activity默认的行为,结果当然是屏蔽了^_^,这一段代码没有留意的同学回去在看一下吧。

       接下来我们把页面切换到这一个网页:

 Android学习指南之二十九:WebView使用详解

       然后我们按下第三个保存图片的按钮,不出意外的话我们截取到了该页的完整图片,并把它保存到了sdcard中了。

       好了,因为篇幅关系,我们关于WebView的功能也只能介绍到这里,关于WebView的其它功能我们在接下来的项目中会涉及到,到时候我们再一起学习,本讲就到这里吧,各位下次再见。

本文发布:Android开发网
本文地址:http://www.teaching4real.com/android/course/205.html
2012年9月16日
发布:鸡啄米 分类:Android开发教程 浏览: 注册送白菜网:0