您的位置:首页 > 移动开发

Android 浏览网页:WebView 嵌入浏览器(浏览历史返回、自定义加载失败界面、支持缩放、获取标题栏)

2015-09-11 10:27 836 查看


一、WebView简介

  在 Android 手机中内置了一款高性能 webkit 内核浏览器,在 SDK 中封装为一个叫做 WebView 组件.我们可以通过对它的美化和包装在自己的应用程序里嵌入一个浏览器。

二、WebView在应用中加载网页的简单用法

WebView的用法实际上非常简单,只需要两步。

1、首先我们在xml布局中添加WebView。

xml文件

[code]<WebView 
         android:id="@+id/webview"
          android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />


2、通过activity设置WebView在当前应用显示(setWebViewClient)和加载页面(loadUrl)

MainActivity

[code]//设置在当前应用中加载网页,不然手机会使用默认浏览器进行打开
  mwebview.setWebViewClient(new WebViewClient());
  //通过网址加载网页
        mwebview.loadUrl("http://www.baidu.com");


这样通过上面两步的操作,我们打开应用网页在联网的状态下就会被直接加载出来了。

三、实现WebView的浏览网页历史回退

  在上面的实例中,我们还需要改进,上面的实例中如果我们通过开始的界面,多次点击浏览其他界面,这时我们如果点击back(我们的返回键)应用就会自动退出,而不是返回上一个界面。因此,我们需要设置一下返回键的返回效果。

在MainActivity中添加如下代码。

[code] @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {      //如果点击的是返回键就进行设置
        if(keyCode==KeyEvent.KEYCODE_BACK){
        //如果浏览器界面可以返回就返回,否则关闭activity
            if(mwebview.canGoBack()){
                mwebview.goBack();
                return true;
            }else{
                finish();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }


效果如开篇图片所示。

四、自定义加载失败页面

  在网络关闭的情况下网页可能会显示加载不出来,我们一般不会采用系统给出的加载失败的界面,一般是自定义。

  自定义加载失败界面有两种方式

  1、可以采用FrameLayout布局,因为帧布局中添加多个控件会像贴小广告一样进行覆盖,这样我们只需要在WebView控件下面添加新的控件,监听页面的加载错误事件,当页面加载出错时,使WebView变为“GONE”,该控件变为“VISIBLE”

  2、我们也可以不采用帧布局,直接对WebView和新控件的可见属性进行设置。

 

[code] <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:id="@+id/erro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="页面加载失败"
            android:visibility="invisible" />
    </FrameLayout>


五、添加进度条

  这里添加了进度条,下面的语句是设置进度条风格为水平进度条。

在帧布局中进度条必须放在WebView下面,不然会被覆盖掉,不进行显示。

[code] <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ProgressBar
            android:id="@+id/progressbar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="invisible" />

        <TextView
            android:id="@+id/erro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="页面加载失败"
            android:visibility="invisible" />
    </FrameLayout>


MainActivity

要实现进度条进度的改变,我们还需要在MainActivity中添加如下语句

[code]        mwebview.getSettings().setJavaScriptEnabled(true);                 mwebview.getSettings().setSupportMultipleWindows(true);
        mwebview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {     
                super.onProgressChanged(view, newProgress);
                progressbar.setProgress(newProgress);

            }
            };


六、实现网页放大与缩小

  我们在手机上查看网页的时候有些网页采取的是自适应的方式,我们打开就能看到网页的完整内容,但是有些网页不是自适应的,我们必须通过放大或者缩小才能看到完整的网页。

  其实实现放大与缩小非常简单只需要添加一行代码。

[code]//支持放缩
mwebview.getSettings().setBuiltInZoomControls(true);


这样添加了放缩功能之后,在放缩的时候你会发现有放缩的控制按钮,我们可以通过下面的代码隐藏放缩控制按钮。

[code]mwebview.getSettings().setDisplayZoomControls(false);


[code]即使我们添加了上面的代码之后会发现还是会存在一定的问题,对指位置放大后,水平方向不能进行滑动了,我们需要一种能够支持无限放大的方式。这种方式也非常简单,我们再来添加一行代码。


[code]//支持无限放大缩小
mwebview.getSettings().setUseWideViewPort(true);


注:1、初始缩放值可这样设置:webView.setInitialScale(initalValue);

  2、缩放后,要使内容适配屏幕,不超出屏幕外显示,实现换行。这方面效果应该由html控制,而不是webview控制。例如
test
实现自动换行。

七、自定义标题栏

  我们可以看到平时的浏览器会有标题栏,我们也来自定义一个标题栏,并实现一定的功能,我这里***的标题栏不很好看,大家凑合看啊。




布局中添加标题栏

[code]<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/btn_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="返回" />

        <TextView
            android:id="@+id/title"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="center"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:text="title" />

        <Button
            android:id="@+id/btn_refesh"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="刷新" />
    </LinearLayout>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ProgressBar
            android:id="@+id/progressbar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="invisible" />

        <TextView
            android:id="@+id/erro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="页面加载失败"
            android:visibility="invisible" />
    </FrameLayout>

</LinearLayout>


MainActivity中通过onReceivedTitle监听

[code]   mwebview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {     
                super.onProgressChanged(view, newProgress);
                progressbar.setProgress(newProgress);

            }
            @Override
            public void onReceivedTitle(WebView view, String title) {
                // TODO Auto-generated method stub
                super.onReceivedTitle(view, title);
                mtitle.setText(title);
            }
        });


八、完整点的代码:

[code]
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_network_detail=(Button) findViewById(R.id.bt_network_detail);
        textview_network_detail=(TextView) findViewById(R.id.textview_netDetail);
        btn_back=(Button) findViewById(R.id.btn_back);
        btn_refesh=(Button) findViewById(R.id.btn_refesh);
        textview_erro=(TextView) findViewById(R.id.erro);
        progressbar=(ProgressBar) findViewById(R.id.progressbar);
        mwebview=(WebView) findViewById(R.id.webview);
        mtitle=(TextView) findViewById(R.id.title);

        mwebview.getSettings().setJavaScriptEnabled(true);
        mwebview.getSettings().setSupportMultipleWindows(true);
        mwebview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {     
                super.onProgressChanged(view, newProgress);
                progressbar.setProgress(newProgress);

            }
            @Override
            public void onReceivedTitle(WebView view, String title) {
                // TODO Auto-generated method stub
                super.onReceivedTitle(view, title);
                mtitle.setText(title);
            }
        });
     //   mwebview.getSettings().setSupportZoom(true);
        //只设置支持放大时会有问题
        //就是你的内容放大的时候会水平方向会有一部分展示不了
        mwebview.getSettings().setBuiltInZoomControls(true);
        //支持无限放大缩小
        //mwebview.getSettings().setUseWideViewPort(true);
        //去掉放缩按钮
   mwebview.getSettings().setDisplayZoomControls(false);

        mwebview.setWebViewClient(new WebViewClient(){          
            @Override
            public void onReceivedError(WebView view, int errorCode,
                    String description, String failingUrl) {
                textview_erro.setVisibility(View.VISIBLE);
                textview_erro.setText("网页加载失败了啊");
                mwebview.setVisibility(View.GONE);
                super.onReceivedError(view, errorCode, description, failingUrl);
            }
           @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
               progressbar.setVisibility(View.VISIBLE);
            super.onPageStarted(view, url, favicon);
        }

           @Override
        public void onPageFinished(WebView view, String url) {
               progressbar.setVisibility(View.INVISIBLE);
            super.onPageFinished(view, url);
        }

        });
        mwebview.loadUrl("http://www.baidu.com/");
        btn_network_detail.setOnClickListener(this);
        //通过ConnectivityManager对象获取当前设备的网络状态,注意要添加权限
        connectionManager=(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);


九、补充

webview有两个方法:

webView.setWebChromeClient和webView.setWebViewClient。

WebChromeClient主要处理解析,渲染网页等浏览器做的事情,辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度。

它里面包括的方法有

  onCloseWindow(关闭WebView)

  onCreateWindow()

  onJsAlert(WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出)

  onProgressChanged

  onReceivedIcon

  onReceivedTitle

WebViewClient是帮助WebView处理各种通知、请求事件的,具体来说包括:

  onLoadResource (下载地址)

  onPageStart

  onPageFinish

  onReceiveError //自定义错误页面就是用的这个方法

  onReceivedHttpAuthRequest
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: