第二十九讲:WebView学习指南 ? { Android学习指南 }

{ Android学习指南 }

适于自学的Andorid学习指南,基于Android 2.2和2.3版本讲解

《Android学习指南》目录

RSS

第二十九讲:WebView学习指南

19 Aug



本讲内容:WebView的使用方法

今天我们来学习一个可以显示网页的控件WebView。WebView的网页渲染引擎和Safari、Chrome一样都是Webkit。使用WebView进行互联网程序开发有以下优点:

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

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

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

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

一、先做一个例子热热身看看效果,例子:通过WebView访问本博客 http://android.yaohuiji.com

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

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

view source

print?

01 <?xml version="1.0" encoding="utf-8"?>

02 <MANIFEST android:versionname="1.0" android:versioncode="1" package="android.basic.lesson29" xmlns:android="http://schemas.android.com/apk/res/android">

03 <APPLICATION android:label="@string/app_name" android:icon="@drawable/icon">

04 <ACTIVITY android:label="@string/app_name" android:name=".MainWebView">

05 <INTENT -filter>

06 <ACTION android:name="android.intent.action.MAIN" />

07 <CATEGORY android:name="android.intent.category.LAUNCHER" />

08 </INTENT>

09 </ACTIVITY>

10

11 </APPLICATION>

12 <USES android:minsdkversion="8" -sdk />

13 <USES android:name="android.permission.INTERNET" -permission />

14 </MANIFEST>

 

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

<?xml version="1.0" encoding="utf-8"?> 4、在Activity文件的OnCreate方法中默认载入一个百度页面,点击按钮时载入预设的网址http://android.yaohuiji.com :view source

print?

01 package android.basic.lesson29;

02

03 import android.app.Activity;

04 import android.os.Bundle;

05 import android.view.View;

06 import android.webkit.WebView;

07 import android.widget.Button;

08 import android.widget.EditText;

09

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 }

 

5、运行程序,查看效果:



点击Go按钮,可以看到本博客出现,不过没有经过任何缩放处理,在接下里的例子我们继续研究,如何做更多的控制。



二、补充一点基础知识:关于WebSettings

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



 

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

//得到WebSettings对象,设置支持Javascript的参数

mWebView.getSettings().setJavaScriptEnabled(true);

//设置可以支持缩放

mWebView.getSettings().setSupportZoom(true);

//设置默认缩放方式尺寸是far

mWebView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);

//设置出现缩放工具

mWebView.getSettings().setBuiltInZoomControls(true);

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

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

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

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



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



四、使用 LoadData 方法加载内容

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

1、新建项目Lesson29_WebView2

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

3、MainWebView2.java 的内容如下:

view source

print?

01 package android.basic.lesson29;

02

03 import java.io.IOException;

04 import java.io.InputStream;

05

06 import org.apache.http.util.ByteArrayBuffer;

07 import org.apache.http.util.EncodingUtils;

08

09 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、运行程序单击第二个按钮,效果如下:



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

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

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

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

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

view source

print?

01 <HTML xmlns="http://www.w3.org/1999/xhtml">

02

03 <HTML xmlns="http://www.w3.org/1999/xhtml">

04 <HEAD>

05

06 <SCRIPT type=text/JavaScript>

07 function alertFuction(){

08 var a=1;

09 var b=2

10 alert(a+b);

11 }

12 function confirmFuction(){

13 confirm("你确定要删除吗?")

14 }

15 </SCRIPT>

16

17 对话框测试

18 <INPUT onclick=alertFuction() type=button value=提醒对话框>

19 <INPUT onclick=confirmFuction() type=button value=选择对话框>

20

21 <A href="test1.html">上一页</A>

 

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

view source

print?

001 package android.basic.lesson29;

002

003 import java.io.FileOutputStream;

004

005 import android.app.Activity;

006 import android.app.AlertDialog;

007 import android.app.AlertDialog.Builder;

008 import android.content.DialogInterface;

009 import android.graphics.Bitmap;

010 import android.graphics.Canvas;

011 import android.graphics.Picture;

012 import android.os.Bundle;

013 import android.view.KeyEvent;

014 import android.view.View;

015 import android.webkit.JsPromptResult;

016 import android.webkit.JsResult;

017 import android.webkit.WebChromeClient;

018 import android.webkit.WebView;

019 import android.webkit.WebViewClient;

020 import android.widget.Button;

021 import android.widget.Toast;

022

023 public class MainWebView3 extends Activity {

024

025 /** Called when the activity is first created. */

026 @Override

027 public void onCreate(Bundle savedInstanceState) {

028 super.onCreate(savedInstanceState);

029 setContentView(R.layout.main);

030

031 // 定义UI组件

032 Button b1 = (Button) findViewById(R.id.Button01);

033 Button b2 = (Button) findViewById(R.id.Button02);

034 Button b3 = (Button) findViewById(R.id.Button03);

035

036 final WebView wv = (WebView) findViewById(R.id.WebView01);

037

038 // 覆盖默认后退按钮的作用,替换成WebView里的查看历史页面

039 wv.setOnKeyListener(new View.OnKeyListener() {

040

041 @Override

042 public boolean onKey(View v, int keyCode, KeyEvent event) {

043 if (event.getAction() == KeyEvent.ACTION_DOWN) {

044 if ((keyCode == KeyEvent.KEYCODE_BACK) && wv.canGoBack()) {

045 wv.goBack();

046 return true;

047 }

048 }

049 return false;

050 }

051 });

052

053 // 设置支持Javascript

054 wv.getSettings().setJavaScriptEnabled(true);

055

056 // 定义并绑定按钮单击监听器

057 b1.setOnClickListener(new View.OnClickListener() {

058 @Override

059 public void onClick(View v) {

060 // 加载URL assets目录下的内容可以用 "file:///android_asset" 前缀

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

062 }

063 });

064

065 // 定义并绑定按钮单击监听器

066 b2.setOnClickListener(new View.OnClickListener() {

067 @Override

068 public void onClick(View v) {

069 // 加载URL assets目录下的内容可以用 "file:///android_asset" 前缀

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

071 }

072 });

073

074 // 定义并绑定按钮单击监听器

075 b3.setOnClickListener(new View.OnClickListener() {

076 @Override

077 public void onClick(View v) {

078 Picture pic = wv.capturePicture();

079 int width = pic.getWidth();

080 int height = pic.getHeight();

081 if (width > 0 && height > 0) {

082 Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

083 Canvas canvas = new Canvas(bmp);

084 pic.draw(canvas);

085 try {

086 String fileName = "sdcard/" + System.currentTimeMillis() + ".png";

087 FileOutputStream fos = new FileOutputStream(fileName);

088

089 if (fos != null) {

090 bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);

091 fos.close();

092 }

093 Toast.makeText(getApplicationContext(), "截图成功,文件名是:" + fileName, Toast.LENGTH_SHORT).show();

094 } catch (Exception e) {

095 e.printStackTrace();

096 }

097 }

098 }

099 });

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

第二十九讲:WebView学习指南 ? { Android学习指南 }
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、运行程序,查看结果:



启动起来时的画面



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



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





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

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



然后我们按下第三个保存图片的按钮,不出意外的话我们截取到了该页的完整图片,并把它保存到了sdcard中了,我在这里展示一下我截取的效果给你看,别被它清晰的效果吓住就行^_^



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

4 Comments

Posted in 1.Android基础篇

Tags: AssetManager, onJsAlert, onJsConfirm, onReceivedTitle, WebChromeClient, WebSettings, WebView, WebViewClient

Leave a Reply

Name (required)

Mail (will not be published) (required)

Website

Comment



  Samcheung

2010/11/26 at 12:07 pm

老师,怎么我截图只能截到一个屏幕大小,而不是整个图片?

Reply

  tcwkid

2010/11/29 at 10:53 pm

讲的很详细 很好

Reply

   antoon_nee

2010/12/16 at 8:21 pm

请问如果页面有多个alert效果。如何在onJsAlert方法中分别设定不同的显示效果呢?

Reply

Anonymous

2011/01/10 at 3:16 pm

[...] [...]

Reply

Search

文章分类

0.Java基础讲座 (23) 1.Android基础篇 (52) 2.Android项目实训篇 (10) 3.Android提高篇 (1) a.Android开发小知识 (23) b.Android教学视频 (4) c.Android Web设计 (1)

日历

February 2011 M T W T F S S

« Jan

1 2 3 4 5 6

7 8 9 10 11 12 13

14 15 16 17 18 19 20

21 22 23 24 25 26 27

28

Archives

January 2011(3) December 2010(8) November 2010(6) October 2010(6) September 2010(22) August 2010(31) July 2010(31)

Tags

AbsoluteLayout adt android android.util.Log android 2.2 android snake architecture Button collapse custom dip eclipse3.6 emulator emulator.exe FrameLayout gravity HelloAndroid hello world Hierarchyview.bat layout layout_gravity layout_span LinearLayout LogCat MusicPlayer notepad onSaveInstanceState padding phone RatingBar Recommended color RelativeLayout scale sdk tools shrink sms sqlite stretch Style TableLayout TableRow Thread video View ViewGroup

Recent Comments

Ivan Ek: I intended to draft you that tiny remark in order to give many thanks again just for the spectacular... Jang: 最上面的“colection”错了,改正:collectio n 集合之间的关系图能译成中文吗 Jang: 集合之间的关系图能译成中文吗 Jang: “内部类对象中不能有静态成员,原因很简单,内部类 的实例对象是外部类实例对象的一个成员。” 在这话里内部类的实例对象是外部类实例对象的一个成员,跟内部类 对象能不能有静态成员.有什么关系呢? wang: 期待中

Blogroll

androgames android.git.kernel.org Android官方镜像 androlib easyicon html5china inspire of site moandroid Yao's Tech Blog 前端观察

Post Views

《Android学习指南》目录 第一讲:Android开发环境的搭建 第十七讲:对话框 Android Dia... 第二讲:Android系统构架分析和应用... 第五讲:用户界面 View(一) 第九讲:用户界面 View(四) 第十六讲:菜单 Android Menu 第四讲:Activity入门指南 第十讲:用户界面 View(五) 第三讲:Android模拟器的使用

Meta

Log in Entries RSS Comments RSS WordPress.org

ChocoTheme by .css{mayo} | powered by WordPress

Entries (RSS) and Comments (RSS)

  

爱华网本文地址 » http://www.413yy.cn/a/25101012/124103.html

更多阅读

转载 第二十八批:又上传了23套易学资料,送给广大易友

原文地址:第二十八批:又上传了23套易学资料,送给广大易友作者:沁阳有易第二十八批:又上传了23套易学资料,送给广大易友好久没跟大家汇报了,跟大家汇报下,我找了一份新的工作,月薪2300包吃住,试用期一个月,在公司做QC,工作还算简单,最近正忙着接

经济学讲义-第二十四讲:货币理论中 作者:本博客管理员

按:本系列文章的作者是本博客管理员(不是张五常教授)!第二十四讲 货币理论(中)从上一讲的学习大家就知道了,由于货币的价值来自于物品的价值,因此要使货币的价值(购买力)保持稳定,必须要使一国之内的货币数量是紧随着实体经济中的物品数量的

第二十四讲:Android动画入门一 ? { Android学习指南 }

本讲内容:Android 动画入门指南1、补间动画2、逐帧动画Android中动画的实现分两种方式,一种方式是补间动画 Teen Animation,就是说你定义一个开始和结束,中间的部分由程序运算得到。另一种叫逐帧动画 Frame Animation,就是说一帧一帧的连

声明:《第二十九讲:WebView学习指南 ? { Android学习指南 }》为网友小蝌蚪找妈妈分享!如侵犯到您的合法权益请联系我们删除