自定义webView,实现带title和返回的webView,监听webView的滑动事件

本文介绍了如何在Android中自定义WebView,包括添加网络请求权限、JavaScript与Android互调、处理页面打开方式、监听webView的滑动事件,并详细讲解了如何获取页面标题和实时更新加载进度。此外,还探讨了常见的webView问题及其解决方案,并分享了自封装webView的实践方法和项目源码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

安卓webView介绍

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.隐藏缩放按钮,实现缩放功能(百度的页面没能缩放,试了其他的一些网页没问题,待解决)

项目源码地址

这个项目我已经发布在GitHub上面,地址为:https://github.com/zhangyanru/WebViewDemo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值