WebView是什么?有什么用途?我们先来看一下官方介绍:
大致意思就是说WebView(网络视图)能加载显示网页,可以将其视为一个浏览器。在使用的过程中需要加入网络权限。了解了WebView我们接下来学习一下怎么使用,本篇博文主要讲解以下内容:
在Activity中创建WebView实例、加载网络资源比较简单,我对代码做了比较详细地注释,直接上代码吧。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private WebView webview;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
//创建WebView实例
webview = (WebView) findViewById(R.id.webview);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (R.id.btn != v.getId())
return;
//跳转到http://www.baidu.com页面
webview.loadUrl("http://www.baidu.com");
}
}
效果图:
public class WebViewActivity extends Activity {
private WebView webview_in;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web_activity);
webview_in = (WebView) findViewById(R.id.webview_in);
//web资源
webview_in.loadUrl("http://www.baidu.com");
//设置WebViewClient客户端
webview_in.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
}
}
效果图:
/**
* 方法描述:启用支持javascript
*/
private void openJavaScript() {
WebSettings settings = webview_in.getSettings();
settings.setJavaScriptEnabled(true);
}
/**
* 方法描述:改写物理按键——返回的逻辑
*
* @param keyCode
* @param event
* @return
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (webview_in.canGoBack()) {
webview_in.goBack();//返回上一页面
return true;
} else {
System.exit(0);//退出程序
}
}
return super.onKeyDown(keyCode, event);
}
现在把改进后的完整代码贴出来:
public class WebViewActivity extends Activity {
private WebView webview_in;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web_activity);
webview_in = (WebView) findViewById(R.id.webview_in);
openJavaScript();
//web资源
webview_in.loadUrl("http://www.baidu.com");
//设置WebViewClient客户端
webview_in.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
}
/**
* 方法描述:启用支持javascript
*/
private void openJavaScript() {
WebSettings settings = webview_in.getSettings();
settings.setJavaScriptEnabled(true);
}
/**
* 方法描述:改写物理按键——返回的逻辑
*
* @param keyCode
* @param event
* @return
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (webview_in.canGoBack()) {
webview_in.goBack();//返回上一页面
return true;
} else {
System.exit(0);//退出程序
}
}
return super.onKeyDown(keyCode, event);
}
}
解决完以上两个问题以后我们再来看一下效果图:
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.webkit.WebView;
import android.widget.ProgressBar;
/**
* Created by lzy on 2016/9/22.
*/
public class ProgressWebView extends WebView {
private ProgressBar progressbar;
public ProgressWebView(Context context) {
super(context);
}
public ProgressWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ProgressWebView(Context context, AttributeSet attrs) {
super(context, attrs);
initProgressBar(context);
setWebChromeClient(new WebChromeClient());
}
private void initProgressBar(Context context) {
progressbar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
progressbar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, dp2px(context, 3), 0, 0));
//改变progressbar默认进度条的颜色(深红色)为Color.GREEN
progressbar.setProgressDrawable(new ClipDrawable(new ColorDrawable(Color.GREEN), Gravity.LEFT, ClipDrawable.HORIZONTAL));
addView(progressbar);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
/**
* 方法描述:根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 类描述:显示WebView加载的进度情况
*/
public class WebChromeClient extends android.webkit.WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
progressbar.setVisibility(GONE);
} else {
if (progressbar.getVisibility() == GONE)
progressbar.setVisibility(VISIBLE);
progressbar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
}
}
我们在布局文件中引入ProgressWebView:
效果图:
package com.lzy.webviewdemo;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
/**
* Created by lzy on 2016/9/22.
*/
public class TinyWebView extends WebView {
private ProgressBar progressbar;
public TinyWebView(Context context) {
super(context);
}
public TinyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public TinyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
initProgressBar(context);
openJavaScript();
setWebViewClient(new WebViewClient());
setWebChromeClient(new WebChromeClient());
}
private void initProgressBar(Context context) {
progressbar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
progressbar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, dp2px(context, 3), 0, 0));
//改变progressbar默认进度条的颜色(深红色)为Color.GREEN
progressbar.setProgressDrawable(new ClipDrawable(new ColorDrawable(Color.GREEN), Gravity.LEFT, ClipDrawable.HORIZONTAL));
addView(progressbar);
}
/**
* 方法描述:启用支持javascript
*/
private void openJavaScript() {
WebSettings settings = getSettings();
settings.setJavaScriptEnabled(true);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
/**
* 方法描述:根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 类描述:显示WebView加载的进度情况
*/
public class WebChromeClient extends android.webkit.WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
progressbar.setVisibility(GONE);
} else {
if (progressbar.getVisibility() == GONE)
progressbar.setVisibility(VISIBLE);
progressbar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
}
}
public class WebViewActivity extends Activity {
private TextView webviewTitle;
private TinyWebView progressWebview;
private String title;
private String webViewUrl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.web_activity);
getData();
initViews();
loadData();
}
/**
* 方法描述:接收数据
*/
private void getData() {
webViewUrl = getIntent().getStringExtra("webview_url");
title = getIntent().getStringExtra("webview_title");
}
/**
* 方法描述:初始化WebView
*/
private void initViews() {
progressWebview = (TinyWebView) findViewById(R.id.progress_webview);
webviewTitle = (TextView) findViewById(R.id.text_webView_title);
//web资源
progressWebview.loadUrl(webViewUrl);
}
/**
* 方法描述:加载数据
*/
private void loadData() {
if (!TextUtils.isEmpty(title))
webviewTitle.setText(title);
if (TextUtils.isEmpty(webViewUrl))
progressWebview.loadUrl(webViewUrl);
}
/**
* 方法描述:改写物理按键——返回的逻辑
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (progressWebview.canGoBack()) {
progressWebview.goBack();//返回上一页面
return true;
} else {
System.exit(0);//退出程序
}
}
return super.onKeyDown(keyCode, event);
}
/**
* 方法描述:
*
* @param activity 发起跳转的Activity
* @param webviewUrl WebView的url
* @param webviewTitle WebView页面的标题
*/
public static void skip(Activity activity, String webviewUrl, String webviewTitle) {
Intent intent = new Intent(activity, WebViewActivity.class);
intent.putExtra("webview_url", webviewUrl);
intent.putExtra("webview_title", webviewTitle);
activity.startActivity(intent);
}
}
使用如下:
WebViewActivity.skip(MainActivity.this,"http://www.baidu.com","百度首页");
感受一下效果:
打油诗
富了投机倒把的
提了吹牛拍马的
树了弄虚作假的
苦了奉公守法的
public class LocalWebViewActivity extends Activity{
private WebView localWebview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_webview_activity);
localWebview = (WebView) findViewById(R.id.local_webview);
WebSettings settings = localWebview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
localWebview.loadUrl("file:///android_asset/myhtmlfile.html");
localWebview.setWebViewClient(new WebViewClient());
}
}
看一下效果如何:
打油诗
富了投机倒把的
提了吹牛拍马的
树了弄虚作假的
苦了奉公守法的
这里要提醒一下,红色的“qwert”就是我们刚才说的“替身”,这个替身可以随意命名,但是注意要与addJavascriptInterface()中的第二个参数一致。
public class LocalWebViewActivity extends Activity{
private WebView localWebview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_webview_activity);
localWebview = (WebView) findViewById(R.id.local_webview);
WebSettings settings = localWebview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
//WebView添加JS要调用的接口,注意参数
localWebview.addJavascriptInterface(new JsInterface(),"qwert");
localWebview.loadUrl("file:///android_asset/myhtmlfile.html");
localWebview.setWebViewClient(new WebViewClient());
}
/**
* 接口描述:供JS调用的接口
*/
public class JsInterface{
/**
* 方法描述:弹出一个Toast
* @param message JS端需要传递的参数(也就是要Toast的内容)
*/
@JavascriptInterface
public void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
}
}
与上一个案例中的代码变化的地方用红色标记了。现在看一下效果:
webview.loadUrl("file:///android_asset/myhtmlfile.html");
2、设置JavaScript可用
WebSettings settings = localWebview.getSettings();
settings.setJavaScriptEnabled(true);
webView.loadUrl("javascript:changeTitle('Android调用JS操控HTML界面')");
打油诗
富了投机倒把的
提了吹牛拍马的
树了弄虚作假的
苦了奉公守法的
为了更能简单地说明问题,我们再建一个Activity类,由于比较简单直接上代码:
/**
* 类描述:Android调用JS
* Created by lzy on 2016/9/22.
*/
public class AndroidInvokeJS extends Activity {
private Button btn_android_invoke_js;
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.android_invoke_js);
btn_android_invoke_js = (Button) findViewById(R.id.btn_android_invoke_js);
webView = (WebView) findViewById(R.id.wv_android_invoke_js);
// ①加载HTML文件
webView.loadUrl("file:///android_asset/myhtmlfile.html");
// ②设置JavaScript可用
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
btn_android_invoke_js.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ③调用HTML中用到的JavaScript方法
webView.loadUrl("javascript:changeTitle('Android调用JS操控HTML界面')");
}
});
}
}
效果图: