在 Android 手机中内置了一款高性能 webkit 内核浏览器,在 SDK 中封装为一个叫做 WebView 组件.我们可以通过对它的美化和包装在自己的应用程序里嵌入一个浏览器。
WebView的用法实际上非常简单,只需要两步。
1、首先我们在xml布局中添加WebView。
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="wrap_content" />
2、通过activity设置WebView在当前应用显示(setWebViewClient)和加载页面(loadUrl)
//设置在当前应用中加载网页,不然手机会使用默认浏览器进行打开
mwebview.setWebViewClient(new WebViewClient());
//通过网址加载网页
mwebview.loadUrl("http://www.baidu.com");
这样通过上面两步的操作,我们打开应用网页在联网的状态下就会被直接加载出来了。
在上面的实例中,我们还需要改进,上面的实例中如果我们通过开始的界面,多次点击浏览其他界面,这时我们如果点击back(我们的返回键)应用就会自动退出,而不是返回上一个界面。因此,我们需要设置一下返回键的返回效果。
在MainActivity中添加如下代码。
@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和新控件的可见属性进行设置。
<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下面,不然会被覆盖掉,不进行显示。
<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中添加如下语句
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);
}
};
我们在手机上查看网页的时候有些网页采取的是自适应的方式,我们打开就能看到网页的完整内容,但是有些网页不是自适应的,我们必须通过放大或者缩小才能看到完整的网页。
其实实现放大与缩小非常简单只需要添加一行代码。
//支持放缩
mwebview.getSettings().setBuiltInZoomControls(true);
这样添加了放缩功能之后,在放缩的时候你会发现有放缩的控制按钮,我们可以通过下面的代码隐藏放缩控制按钮。
mwebview.getSettings().setDisplayZoomControls(false);
即使我们添加了上面的代码之后会发现还是会存在一定的问题,对指位置放大后,水平方向不能进行滑动了,我们需要一种能够支持无限放大的方式。这种方式也非常简单,我们再来添加一行代码。
//支持无限放大缩小
mwebview.getSettings().setUseWideViewPort(true);
注:1、初始缩放值可这样设置:webView.setInitialScale(initalValue);
2、缩放后,要使内容适配屏幕,不超出屏幕外显示,实现换行。这方面效果应该由html控制,而不是webview控制。例如
test
实现自动换行。 我们可以看到平时的浏览器会有标题栏,我们也来自定义一个标题栏,并实现一定的功能,我这里制作的标题栏不很好看,大家凑合看啊。
布局中添加标题栏
<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监听
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);
}
});
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