前言
在智能移动设备上打开浏览器浏览网页是移动用户很经常的操作。本文就来讲解Android中一个可以进行网页显示的控件WebView。同Chrome和Safari一样,WebView的网页渲染引擎也是Webkit。
使用WebView控件进行Android互联网程序开发又如下优势:
- 1、可以打开远程网址、也可以加载本地Html数据。
- 2、可以搭建Java和Javascript交互桥梁。
- 3、WebView控件可以高度定制。
下面我们通过几个例子来学习WebView的使用方法。
WebView访问一个网站
1、先来一个简单的例子,新建一个项目Lesson29_WebView。
2、因为要访问互联网所以先在AndroidManifest.xml中设定权限:
3、在res/layout/main.xml中放置一个输入框,一个按钮和一个WebView:
4、在Activity文件的OnCreate方法中默认载入一个百度页面,点击按钮时载入预设的网址:
运行程序,在编辑框中输入一个网址,点击Go按钮,就可以看到该网页显示,不过没有经过任何缩放处理,在接下里的例子我们继续研究,如何做更多的控制。
WebSettings基础知识
1、先看一下WebView的继承关系,可以看到它不是在android.widget包中,而是在android.webkit包中。
2、WebSettings :WebView组件有一个辅助类叫WebSettings,它管理WebView的设置状态。该对象可以通过WebView.getSettings()方法获得。下面举几个例子来说明WebSettings的用法:
加载assets目录下的本地网页
WebView调用assets目录下的本地网页和图片等资源非常方便,使用形如:
在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 的内容如下:
4、运行程序单击第二个按钮,效果如下:
对比上面的例子,我们可以看到两个明显的区别,其一,图片没加载出来,其二链接失效,点击后无法加载test1.html 。
WebChromeClient和WebViewClient
和WebView相关的辅助对象,除了WebSettings以外还有WebChromeClient和WebViewClient。
接下来的这个例子内容比较丰富,虽然注释比较清晰,但是您一次消化起来还是比较困难的,因此您需要的是一点点耐心,多看几遍,最重要的是自己至少敲代码敲一遍。
1、在上面的例子中继续增加内容,增加test3.html的内容:
2、MainWebView3.java的内容,请注意注释内容:
3、运行程序,查看结果:
启动起来时的画面:
点击第一个按钮,我们可以看到WebViewClient对象中定义的方法的确被调用了。
点击第二个按钮,我们看到加载的网页中有两个按钮,我们知道默认情况下Android会直接忽略掉由javascript弄出来的alert等弹出信息,除非我们在WebChromeClient中覆盖onJsAlert()方法和onJsConfirm()方法,让我们分别点击它们看看效果。
接下来我们在页面中跳转几次后,使用后退按钮,查看我们是否屏蔽了Activity默认的行为,结果当然是屏蔽了,接下来我们把页面切换到这一个网页:
然后我们按下第三个保存图片的按钮,不出意外的话我们截取到了该页的完整图片,并把它保存到了sdcard中了。
WebView出现的乱码问题
webview加载网页源码乱码问题
一、webView.loadUrl();
直接显示网页内容(单独显示网络图片),一般不会出现乱码。
二、webView.loadData(data, “text/html”, “UTF-8”);
loadData主要被设计用来装载URI格式的数据,它不能通过网络来加载内容。网上流传的webview加载中文出现乱码,多数是使用此方法。使用过程中主要有两个问题:
(1)loadData不能加载图片内容,如果想加载图片内容或者获得更强大的Web支持建议使用更强大的loadDataWithBaseURL.
(2)许多实用loadData方法的朋友都遇到显示乱码的问题,那是因为编码器设置错误导致的。我们知道String类型的数据主要是unicode编码,而WebView一般为了节省资源使用的是UTF-8编码,所以我们在loadData的时候要告诉方法怎样转码。即要告诉它要将unicode编码的内容转成UTF-8编码的内容。有些朋友虽然在loadData的时候设置了编码方式,但是还是显示乱码,这是因为还需要为WebView的text编码指定编码方式。举例如下:
(3)网页说明编码格式
以上两种方法是网上给的比较好的方法,但是我都试了下都没有解决我的乱码问题。 原来我是用LoadData方法来解析html的,但是据说这是官方的一个BUG,不能用来解析中文。所以绕其道而行之,采用loadDataWithBaseURL的方法,其中codeingType设置为utf-8就OK了。3、loadDataWithBaseURL如果单纯显示文字的话可以写:
如果要显示图片可以写:
其中baseUrl为你存储照片的路径。
自定义webview组件
package com.xp.lvbh.others.widget.h5;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.util.AttributeSet;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import com.xp.lvbh.system.LApplication;
/**
* 自定义webview
* @author ares
*/
@SuppressLint("SetJavaScriptEnabled")
public class MyWebView extends WebView {
private Context context;
public MyWebView(Context context) {
super(context);
this.context = context;
init();
}
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
// public MyWebView(Context context, AttributeSet attrs, int defStyle) {
// super(context, attrs, defStyle);
// this.context = context;
// init();
// }
@SuppressLint({"NewApi", "JavascriptInterface"})
public void init() {
WebSettings settings = this.getSettings();
// 开启javascript设置
settings.setJavaScriptEnabled(true);
// 设置可以使用localStorage
settings.setDomStorageEnabled(true);
// 开启Application H5 Caches 功能
settings.setAppCacheEnabled(true);
// 编码格式
settings.setDefaultTextEncodingName("utf-8");
// 设置Application Caches 缓存目录
settings.setAppCachePath(LApplication.H5_CACHE_PATH);
// 默认使用缓存
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
// 可以读取文件缓存(manifest生效)
settings.setAllowFileAccess(true);
// 滚动条风格,为0指滚动条不占用空间,直接覆盖在网页上
this.setScrollBarStyle(SCROLLBARS_INSIDE_OVERLAY);
// 加快HTML网页加载完成速度
if (Build.VERSION.SDK_INT >= 19) {
settings.setLoadsImagesAutomatically(true);
} else {
settings.setLoadsImagesAutomatically(false);
}
// this.addJavascriptInterface(new Android(context), "android");
this.addJavascriptInterface(new Android(context), "android");
this.setBackgroundColor(Color.WHITE);
}
// WebView cookies清理
public void clearCookies() {
CookieSyncManager.createInstance(context);
CookieSyncManager.getInstance().startSync();
CookieManager.getInstance().removeSessionCookie();
}
// WebView cache清理
public void clearCache() {
this.clearCache(true);
this.clearHistory();
}
// 判断WebView是否已经滚动到页面底端
public boolean isScrollBottom() {
// getScrollY()方法返回的是当前可见区域的顶端距整个页面顶端的距离,也就是当前内容滚动的距离.
// getHeight()或者getBottom()方法都返回当前WebView 这个容器的高度
// getContentHeight 返回的是整个html 的高度,但并不等同于当前整个页面的高度,因为WebView 有缩放功能,
// 所以当前整个页面的高度实际上应该是原始html 的高度再乘上缩放比例
return this.getContentHeight() * this.getScaleY() == (this.getHeight() + this.getScrollY());
}
}