如何监听webview的滚动事件
1个回答
展开全部
WebView是基于webkit引擎展现web页面的控件,它功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。
WebView有几个可以定制的点:
(1)设置WebChromeClient子类,WebChromeClient会在一些影响浏览器ui交互动作发生时被调用,比如WebView关闭和隐藏、页面加载进展、js确认框和警告框、js加载前、js操作超时、webView获得焦点等等,详见WebChromeClient
(2)设置WebViewClient子类,WebViewClient会在一些影响内容喧嚷的动作发生时被调用,比如表单的错误提交需要重新提交、页面开始加载及加载完成、资源加载中、接收到http认证需要处理、页面键盘响应、页面中的url打开处理等等,详见WebViewClient
(3)设置WebSettings类,其中包含多项配置。WebSettings用来对WebView的配置进行配置和管理,比如是否可以进行文件操作、缓存的设置、页面是否支持放大和缩小、是否允许使用数据库api、字体及文字编码设置、是否允许js脚本运行、是否允许图片自动加载、是否允许数据及密码保存等等,详见WebSettings
(4)设置addJavascriptInterface方法,将java对象绑定到webView中,以方便从页面js中控制java对象,实现用本地java代码和html页面进行交互,甚至可以进行页面自动化。但如此做存在安全隐患,所以若设置了此方法,请确保webView的代码都是自己完成
webView的基本使用方法
添加网络请求权限
在AndroidManifest.xml中添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
JavaScript和Android代码互调
通过WebView,我们可以在JavaScript代码和客户端代码之间创建接口。
比如,我们希望通过Android的Toast展示信息,而不是通过JavaScript的alert()函数。
想要实现这样的功能,我们只需要做以下三步:
1.定义的MyJavaScriptInterface类
public class MyJavaScriptInterFace {
Context mContext;
public MyJavaScriptInterFace(Context context){
mContext = context;
}
public void showToast(String toast){
Toast.makeText(mContext,toast,Toast.LENGTH_SHORT).show();
}
}
2.通过addJavaScriptInterface()函数绑定接口
webView.addJavaScriptInterface(new MyJavaScriptInterface(this),"Android");
3.在JavaScript中使用这个接口
<script type="text/javascript">
function showAndroidToast(toast){
Android.showToast(toast);
}
</script>
处理页面是在webView打开还是在浏览器打开
当我们点击一个WebView中的页面链接的时候,默认是让Android启动一个可以处理Url的应用(比如,浏览器),那么怎样让Url继续在WebView中打开呢?
只需要做以下几步:
1.继承WebViewClient类,覆盖shouldOverrideUrlLoading方法
public class MyWebViewClient extends WebViewClient {
private Context mContext;
public MyWebViewClient(Context context){
mContext = context;
}
/**
* 控制加载链接的位置,false仍然在webView中加载
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.contains("baidu.com")){ //访问百度的站点都在webView中访问
return false;
}
//非百度站点打开浏览器访问
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
mContext.startActivity(intent);
return true;
}
}
2.调用webView的setWebViewClient()方法
webView.setWebViewClient(new MyWebViewClient(context));
页面历史记录导航
当WebView覆盖了URL加载时(就是跳转了几个URL页面),会产生历史记录。可以用webView.canGoBack()判断是否有历史页面,用webView.goBack();回到历史页面。
实时更新页面的获取进度
假如你需要通过进度条展示WebView的页面打开进度,就需要获取当前页面的进度,我们通过继承WebViewClient类,覆盖onLoadResource方法来实现实时获取进度
public class MyWebViewClient extends WebViewClient {
private Context mContext;
private OnPageUpdateListener onPageUpdateListener;
public interface OnPageUpdateListener{
void onProgressUpdate(int newProgress);
void onGetTitle(String title);
}
public MyWebViewClient(Context context){
mContext = context;
}
/**
* 控制加载链接的位置,false仍然在webView中加载
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.contains("baidu.com")){ //访问百度的站点都在webView中访问
return false;
}
//非百度站点打开浏览器访问
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
mContext.startActivity(intent);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(onPageUpdateListener!=null){
onPageUpdateListener.onGetTitle(view.getTitle());
}
}
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
Log.d("zyr","onLoadResource url:" + url + " progress:" + view.getProgress());
if(onPageUpdateListener!=null){
onPageUpdateListener.onProgressUpdate(view.getProgress());
if(view.getTitle()!=null){
onPageUpdateListener.onGetTitle(view.getTitle());
}
}
}
public void setOnPageUpdateListener(OnPageUpdateListener onPageUpdateListener) {
this.onPageUpdateListener = onPageUpdateListener;
}
}
获取页面的title
同样的,我们通过继承WebViewClient类,覆盖onPageFinied方法获取页面Title
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(onPageUpdateListener!=null){
onPageUpdateListener.onGetTitle(view.getTitle());
}
}
webView滚动事件监听
我们通过覆盖WebView的OnScrollChanged方法来获取滚动事件
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(onScrollChangedCallBack != null){
onScrollChangedCallBack.onWebViewScroll(l - oldl, t - oldt);
if(getContentHeight() * getScale() == getHeight() + getScrollY()){
onScrollChangedCallBack.onWebViewScrollToEnd();
}
}
}
webView一些常见的问题和解决方法
1.WebChromeClient的onReceivedTitle方法有时候在goBack的时候得不到title,经测试,用上面的方法可以得到
自己封装一个webView
实现的功能有:
1.向下滑动一定距离隐藏Title,向上滑动显示Title
2.滑动到底部弹出Toast
3.用进度条显示页面打开进度
4.按顶部返回按钮和Back按键能够返回上一次打开的页面,当没有历史时,关闭Activity
5.点击顶部Close按钮关闭Activity
6.隐藏缩放按钮,实现缩放功能(百度的页面没能缩放,试了其他的一些网页没问题,待解决)
WebView有几个可以定制的点:
(1)设置WebChromeClient子类,WebChromeClient会在一些影响浏览器ui交互动作发生时被调用,比如WebView关闭和隐藏、页面加载进展、js确认框和警告框、js加载前、js操作超时、webView获得焦点等等,详见WebChromeClient
(2)设置WebViewClient子类,WebViewClient会在一些影响内容喧嚷的动作发生时被调用,比如表单的错误提交需要重新提交、页面开始加载及加载完成、资源加载中、接收到http认证需要处理、页面键盘响应、页面中的url打开处理等等,详见WebViewClient
(3)设置WebSettings类,其中包含多项配置。WebSettings用来对WebView的配置进行配置和管理,比如是否可以进行文件操作、缓存的设置、页面是否支持放大和缩小、是否允许使用数据库api、字体及文字编码设置、是否允许js脚本运行、是否允许图片自动加载、是否允许数据及密码保存等等,详见WebSettings
(4)设置addJavascriptInterface方法,将java对象绑定到webView中,以方便从页面js中控制java对象,实现用本地java代码和html页面进行交互,甚至可以进行页面自动化。但如此做存在安全隐患,所以若设置了此方法,请确保webView的代码都是自己完成
webView的基本使用方法
添加网络请求权限
在AndroidManifest.xml中添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
JavaScript和Android代码互调
通过WebView,我们可以在JavaScript代码和客户端代码之间创建接口。
比如,我们希望通过Android的Toast展示信息,而不是通过JavaScript的alert()函数。
想要实现这样的功能,我们只需要做以下三步:
1.定义的MyJavaScriptInterface类
public class MyJavaScriptInterFace {
Context mContext;
public MyJavaScriptInterFace(Context context){
mContext = context;
}
public void showToast(String toast){
Toast.makeText(mContext,toast,Toast.LENGTH_SHORT).show();
}
}
2.通过addJavaScriptInterface()函数绑定接口
webView.addJavaScriptInterface(new MyJavaScriptInterface(this),"Android");
3.在JavaScript中使用这个接口
<script type="text/javascript">
function showAndroidToast(toast){
Android.showToast(toast);
}
</script>
处理页面是在webView打开还是在浏览器打开
当我们点击一个WebView中的页面链接的时候,默认是让Android启动一个可以处理Url的应用(比如,浏览器),那么怎样让Url继续在WebView中打开呢?
只需要做以下几步:
1.继承WebViewClient类,覆盖shouldOverrideUrlLoading方法
public class MyWebViewClient extends WebViewClient {
private Context mContext;
public MyWebViewClient(Context context){
mContext = context;
}
/**
* 控制加载链接的位置,false仍然在webView中加载
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.contains("baidu.com")){ //访问百度的站点都在webView中访问
return false;
}
//非百度站点打开浏览器访问
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
mContext.startActivity(intent);
return true;
}
}
2.调用webView的setWebViewClient()方法
webView.setWebViewClient(new MyWebViewClient(context));
页面历史记录导航
当WebView覆盖了URL加载时(就是跳转了几个URL页面),会产生历史记录。可以用webView.canGoBack()判断是否有历史页面,用webView.goBack();回到历史页面。
实时更新页面的获取进度
假如你需要通过进度条展示WebView的页面打开进度,就需要获取当前页面的进度,我们通过继承WebViewClient类,覆盖onLoadResource方法来实现实时获取进度
public class MyWebViewClient extends WebViewClient {
private Context mContext;
private OnPageUpdateListener onPageUpdateListener;
public interface OnPageUpdateListener{
void onProgressUpdate(int newProgress);
void onGetTitle(String title);
}
public MyWebViewClient(Context context){
mContext = context;
}
/**
* 控制加载链接的位置,false仍然在webView中加载
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.contains("baidu.com")){ //访问百度的站点都在webView中访问
return false;
}
//非百度站点打开浏览器访问
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
mContext.startActivity(intent);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(onPageUpdateListener!=null){
onPageUpdateListener.onGetTitle(view.getTitle());
}
}
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
Log.d("zyr","onLoadResource url:" + url + " progress:" + view.getProgress());
if(onPageUpdateListener!=null){
onPageUpdateListener.onProgressUpdate(view.getProgress());
if(view.getTitle()!=null){
onPageUpdateListener.onGetTitle(view.getTitle());
}
}
}
public void setOnPageUpdateListener(OnPageUpdateListener onPageUpdateListener) {
this.onPageUpdateListener = onPageUpdateListener;
}
}
获取页面的title
同样的,我们通过继承WebViewClient类,覆盖onPageFinied方法获取页面Title
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(onPageUpdateListener!=null){
onPageUpdateListener.onGetTitle(view.getTitle());
}
}
webView滚动事件监听
我们通过覆盖WebView的OnScrollChanged方法来获取滚动事件
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(onScrollChangedCallBack != null){
onScrollChangedCallBack.onWebViewScroll(l - oldl, t - oldt);
if(getContentHeight() * getScale() == getHeight() + getScrollY()){
onScrollChangedCallBack.onWebViewScrollToEnd();
}
}
}
webView一些常见的问题和解决方法
1.WebChromeClient的onReceivedTitle方法有时候在goBack的时候得不到title,经测试,用上面的方法可以得到
自己封装一个webView
实现的功能有:
1.向下滑动一定距离隐藏Title,向上滑动显示Title
2.滑动到底部弹出Toast
3.用进度条显示页面打开进度
4.按顶部返回按钮和Back按键能够返回上一次打开的页面,当没有历史时,关闭Activity
5.点击顶部Close按钮关闭Activity
6.隐藏缩放按钮,实现缩放功能(百度的页面没能缩放,试了其他的一些网页没问题,待解决)
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询