3.是否存在滚动条
当我们做类似上拉加载下一页这样的功能的时候,页面初始的时候需要知道当前WebView是否存在纵向滚动条,如果有则不加载下一页,如果没有则加载下一页直到其出现纵向滚动条。首先继承WebView类,在子类添加下面的代码:
public boolean existVerticalScrollbar () {
return computeVerticalScrollRange() > computeVerticalScrollExtent();
}
computeVerticalScrollRange得到的是可滑动的最大高度,computeVerticalScrollExtent得到的是滚动把手自身的高,当不存在滚动条时,两者的值是相等的。当有滚动条时前者一定是大于后者的。
4.是否已滚动到页面底部
同样我们在做上拉加载下一页这样的功能时,也需要知道当前页面滚动条所处的状态,如果快到底部,则要发起网络请求数据更新网页。同样继承WebView类,在子类覆盖onScrollChanged方法,具体如下:
@Override
protected void onScrollChanged(int newX, int newY, int oldX, int oldY) {
super.onScrollChanged(newX, newY, oldX, oldY);
if (newY != oldY) {
float contentHeight = getContentHeight() * getScale();
// 当前内容高度下从未触发过, 浏览器存在滚动条且滑动到将抵底部位置
if (mCurrContentHeight != contentHeight && newY > 0 && contentHeight <= newY + getHeight() + mThreshold) {
// TODO Something...
mCurrContentHeight = contentHeight;
}
}
}
上面mCurrContentHeight用于记录上次触发时的网页高度,用来防止在网页总高度未发生变化而目标区域发生连续滚动时会多次触发TODO,mThreshold是一个阈值,当页面底部距离滚动条底部的高度差<=这个值时会触发TODO。
5.远程网页需访问本地资源
当我们在WebView中加载出从web服务器上拿取的内容时,是无法访问本地资源的,如assets目录下的图片资源,因为这样的行为属于跨域行为(Cross-Domain),而WebView是禁止的。解决这个问题的方案是把html内容先下载到本地,然后使用loadDataWithBaseURL加载html。这样就可以在html中使用 file:///android_asset/xxx.png 的链接来引用包里面assets下的资源了。示例如下:
private void loadWithAccessLocal(final String htmlUrl) {
new Thread(new Runnable() {
public void run() {
try {
final String htmlStr = NetService.fetchHtml(htmlUrl);
if (htmlStr != null) {
TaskExecutor.runTaskOnUiThread(new Runnable() {
@Override
public void run() {
loadDataWithBaseURL(htmlUrl, htmlStr, "text/html", "UTF-8", "");
}
});
return;
}
} catch (Exception e) {
Log.e("Exception:" + e.getMessage());
}
TaskExecutor.runTaskOnUiThread(new Runnable() {
@Override
public void run() {
onPageLoadedError(-1, "fetch html failed");
}
});
}
}).start();
}
上面有几点需要注意:
•从网络上下载html的过程应放在工作线程中
•html下载成功后渲染出html的步骤应放在UI主线程,不然WebView会报错
•html下载失败则可以使用我们前面讲述的方法来显示自定义错误界面
|
|