在平常的開發中我們一般都會使用到混合開發,比如H5+原生,如果你的app使用到H5開發,那麼webview使用是不可或缺的。所以掌握WebView的知識是多麼重要。 本文要帶你溜WebView,讓你掌握WebView的基本開發,包括與javaSript的互動。 先看下效果圖
這裡首先點選“hello world” 然後javaSript彈出一個alert彈框,接著JavaScript呼叫java的clickText函式,通過回撥,彈出一個toast提示。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="lwj.com.webview.WebViewActivity">
<WebView
android:id="@+id/id_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
複製程式碼
佈局就一個webview顯示網頁
public class WebViewActivity extends AppCompatActivity {
private static final String TAG = "WebViewActivity";
private WebView webView;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
webView = (WebView) this.findViewById(R.id.id_webview);
WebSettings webSetting = webView.getSettings();
webSetting.setDefaultTextEncodingName("utf-8");
webSetting.setJavaScriptEnabled(true);//支援js
webSetting.setUseWideViewPort(false);//設定此屬性,可任意縮放比例
webSetting.setTextZoom(100);//設定字型,相對於正常字型的百分比
webSetting.setLoadWithOverviewMode(true);
webSetting.setDomStorageEnabled(true);// 開啟DOM storage
webView.setWebChromeClient(webChromeClient);
webView.setWebViewClient(webViewClient);
String s1 = getHtmlStr("hello world");
webView.loadData(s1, "text/html", "utf-8");
//與js互動
JsToAndroidInterface jsToAndroid = new JsToAndroidInterface();
jsToAndroid.setOnClickListener(new JsToAndroidInterface.OnTextClickListener() {
@Override
public void onTextClick(final String str) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(WebViewActivity.this,str,Toast.LENGTH_SHORT).show();
}
});
}
});
webView.addJavascriptInterface(jsToAndroid, JsToAndroidInterface.INTERFACE_NAME);
}
/**
* html資料
* @param str
* @return
*/
public static String getHtmlStr(String str) {
StringBuilder builder = null;
try {
builder = new StringBuilder();
builder.append("<html><head>");
builder.append(" <script language=\"javascript\">function s(){\n" +
"alert(\""+str+"!\");\n" +
"window.clickOnAndroid.clickText(\""+str+"\");\n" +
"}</script>");
builder.append("</head><body><div class=\"container\"><div class=\"content\">");
builder.append("<a href=\"javascript:void(0);\" onclick=\"s()\">").append(str).append("</a>");
builder.append("</div></div></body></html>");
} catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
/**
* 處理各種通知
* 請求事件相關
*/
private WebViewClient webViewClient = new WebViewClient() {
/**
* 開始載入頁面回撥
* @param view
* @param url
* @param favicon
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.i(TAG, "onPageStarted");
super.onPageStarted(view, url, favicon);
}
/**
* 攔截url跳轉
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//當前的webview跳轉
webView.loadUrl(url);
return true;
}
/**
* 在每一次請求資源時回撥
* @param view
* @param request
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Log.i(TAG, "shouldOverrideUrlLoading");
return super.shouldOverrideUrlLoading(view, request);
}
/**
* 載入完成回撥
* @param view
* @param url
*/
@Override
public void onPageFinished(WebView view, String url) {
Log.i(TAG, "onPageFinished");
super.onPageFinished(view, url);
}
/**
* 載入錯誤回撥
* 在這做錯誤處理
* @param view
* @param request
* @param error
*/
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
Log.i(TAG, "onReceivedError");
super.onReceivedError(view, request, error);
}
/**
* https錯誤回撥
* 可做錯誤處理
* @param view
* @param request
* @param errorResponse
*/
@Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
Log.i(TAG, "onReceivedHttpError");
super.onReceivedHttpError(view, request, errorResponse);
}
/**
* 載入頁面資源回撥
* @param view
* @param url
*/
@Override
public void onLoadResource(WebView view, String url) {
Log.i(TAG, "onLoadResource");
super.onLoadResource(view, url);
}
};
/**
* 處理瀏覽器相關的事件
* 如處理JavaScript的對話方塊
* 圖示、title、載入進度
*/
private WebChromeClient webChromeClient = new WebChromeClient() {
/**
* javasript 的alert彈框呼叫
* @param view
* @param url
* @param message
* @param result
* @return
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
Log.i(TAG, "onJsAlert");
AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
dlg.setTitle("提示");
dlg.setMessage(message);
dlg.setButton(AlertDialog.BUTTON_POSITIVE, "確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
result.confirm();
}
});
dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
result.cancel();
}
});
dlg.show();
return true;
}
/**
* js的Confirm彈框
* @param view
* @param url
* @param message
* @param result
* @return
*/
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
dlg.setTitle("提示");
dlg.setMessage(message);
dlg.setButton(AlertDialog.BUTTON_POSITIVE, "確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
result.confirm();
}
});
dlg.setButton(AlertDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
result.cancel();
}
});
dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
result.cancel();
}
});
dlg.show();
return true;
}
/**
* 處理js prompt彈框
* @param view
* @param url
* @param message
* @param defaultValue
* @param result
* @return
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
Log.i(TAG, "onJsPrompt");
return super.onJsPrompt(view, url, message, defaultValue, result);
}
/**
* 載入網頁進度條
* @param view
* @param newProgress
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
Log.i(TAG, "onProgressChanged" + newProgress);
super.onProgressChanged(view, newProgress);
}
/**
* 網頁的title
* @param view
* @param title
*/
@Override
public void onReceivedTitle(WebView view, String title) {
Log.i(TAG, "onReceivedTitle" + title);
super.onReceivedTitle(view, title);
}
};
/**
* 實現在歷史頁面中 Back
* 要在當前 Activity
* 中處理並消費掉該 Back事件:
*/
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
複製程式碼
這裡首先通過WebSettings設定webview支援的型別,包括與JavaScript互動的設定,然後載入html資料,並且設定與JavaScript互動的物件(JsToAndroidInterface),還有關於WebViewClient和WebChromeClient介紹,裡面方法的作用與處理,具體的可以看註釋,最後對webView.goBack()的處理.
public class JsToAndroidInterface {
public static final String INTERFACE_NAME = "clickOnAndroid";
private OnTextClickListener mClickListener;
/**
* 供js呼叫函式
* @param str
*/
@JavascriptInterface
public void clickText(final String str)
{
if(mClickListener != null)
{
mClickListener.onTextClick(str);
}
}
/**
* 回撥介面
*/
public interface OnTextClickListener
{
void onTextClick(String str);
}
/**
* 設定回撥
* @param listener
*/
public void setOnClickListener(OnTextClickListener listener)
{
mClickListener = listener;
}
}
複製程式碼
這是與JavaScript互動的物件,JavaScript呼叫clickText,通過回撥給使用者呼叫. 看了本文,應該都瞭解webview的常用知識了吧.