一充包、前言:
在 Android 中我們要給 js 傳遞參數(shù)娃善;js 也會給我們傳遞參數(shù)多柑;有時候也要拿到 js 的點擊事件奶是,來完成 app 本地操作。
WebView 常見的坑: 點擊查看:
1. Activity中的使用:
public class MyAgreementDetailsActivity extends BaseDaggerActivity<MyAgreementDetailsPresenter> implements MyAgreementDetailsContract.View {
@Inject
MyAgreementDetailsPresenter myAgreementPresenter;
@BindView(R.id.iv_main_back)
ImageView ivMainBack;
@BindView(R.id.tv_main_title)
TextView tvMainTitle;
@BindView(R.id.iv_main_clock)
ImageView ivMainClock;
@BindView(R.id.rl_title)
RelativeLayout rlTitle;
@BindView(R.id.progressBar1)
ProgressBar progressBar1;
@BindView(R.id.webview)
CustWebView webview;
private String agreementName;
private String agreementId;
private String url;
private int nper;
private int agrType;
private int isChange;
private String token;
private boolean isFirst = false;
public static void launch(Context context, String agreement_id, String agreement_name, int nper, String url, int agr_type, int is_change) {
Intent intent = new Intent(context, MyAgreementDetailsActivity.class);
intent.putExtra("agreementName", agreement_name);
intent.putExtra("agreementId", agreement_id);
intent.putExtra("url", url);
intent.putExtra("nper", nper);
intent.putExtra("agrType", agr_type);
intent.putExtra("isChange", is_change);
context.startActivity(intent);
}
@Override
public MyAgreementDetailsPresenter createPresent() {
return myAgreementPresenter;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_agreement_view);
ButterKnife.bind(this);
initEvent();
initData();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@SuppressLint("JavascriptInterface")
private void initData() {
token = SPUtils.getInstance(SPConstant.TOKEN).getString(SPConstant.TOKEN);
agreementName = getIntent().getStringExtra("agreementName");
//協(xié)議id
agreementId = getIntent().getStringExtra("agreementId");
//期數(shù)
nper = getIntent().getIntExtra("nper", 0);
//跳轉(zhuǎn)鏈接
url = getIntent().getStringExtra("url");
agrType = getIntent().getIntExtra("agrType", 0);
isChange = getIntent().getIntExtra("isChange", 0);
tvMainTitle.setText(agreementName);
final WebSettings webSettings = webview.getSettings();
//啟用JS
webSettings.setJavaScriptEnabled(true);
//設(shè)置是否支持變焦
webSettings.setSupportZoom(true);
//縮放
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
//多窗口
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportMultipleWindows(true);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
webSettings.setDefaultFontSize(18);
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
//啟用緩存
webSettings.setAppCacheEnabled(true);
webSettings.setAllowFileAccess(true);
//
webSettings.setDomStorageEnabled(true);
//設(shè)置緩存模式
webSettings.setBlockNetworkImage(false);
//解決圖片不顯示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
try {
if (Build.VERSION.SDK_INT >= 16) {
Class<?> clazz = webview.getSettings().getClass();
Method method = clazz.getMethod(
"setAllowUniversalAccessFromFileURLs", boolean.class);//利用反射機制去修改設(shè)置對象
if (method != null) {
method.invoke(webview.getSettings(), true);//修改設(shè)置
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
webview.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
// TODO 自動生成的方法存根
if (newProgress == 100) {
progressBar1.setVisibility(View.GONE);//加載完網(wǎng)頁進度條消失
} else {
progressBar1.setVisibility(View.VISIBLE);//開始加載網(wǎng)頁時顯示進度條
progressBar1.setProgress(newProgress);//設(shè)置進度值
}
}
});
webview.loadUrl(url);
//在js中調(diào)用本地java方法 callAndroid
webview.addJavascriptInterface(new JsInterface(this), "click");
//允許調(diào)試
if (BuildConfig.DEBUG){
WebView.setWebContentsDebuggingEnabled(true);
}else {
WebView.setWebContentsDebuggingEnabled(false);
}
/**
* webView 加載的時候 會跳到手機自帶的瀏覽器
* 給自己定義個webview添加客戶端
*/
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// webview.loadUrl("javascript:loadingDate(' " + mLoginSMSBean.getToken() + " ' ,'" + mAgreementBean.getAgreement_id() + "' ,'" + "2" + "','" + mAgreementBean.getAgr_type() + "','" + mAgreementBean.getNper() + "' ,'" + mAgreementBean.getIs_change() + "' )");
if (!isFirst) {
isFirst = true;
webview.loadUrl("javascript:loadingDate('" + token + "','" + agreementId + "','" + "2" + "','" + agrType + "','" + nper + "','" + isChange + "' )");
// LogUtils.d("LUO", "===" + token);
}
}
});
webview.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
//按返回鍵操作并且能回退網(wǎng)頁
if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) {
//后退
webview.goBack();
return true;
}
}
return false;
}
});
}
private void initEvent() {
//返回
ivMainBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
@Override
public void onError(String error) {
ToastUtils.showShort(error);
}
@Override
public void AgreementDetailsSuccess(BaseHttpResponse<ResponseEmptyDataBean> data) {
ToastUtils.showShort("協(xié)議簽署成功");
finish();
}
/**
* 2.編寫一個提供給Web的Js接口類
*/
public class JsInterface {
private Context mContext;
public JsInterface(Context context) {
this.mContext = context;
}
//在js中調(diào)用window.AndroidWebView.showInfoFromJs(name)竣灌,便會觸發(fā)此方法聂沙。
@JavascriptInterface
public void clickAction(String json, String flag) {
if(!TextUtils.isEmpty(json)){
JsBean jsBean = JSON.parseObject(json, JsBean.class);
submitData(jsBean);
}
// LogUtils.d("LUO", json + "==========" + flag);
// ToastUtils.showShort("點擊了按鈕");
}
}
private void submitData(JsBean jsBean) {
HashMap map = new HashMap();
map.put("agreement_id",agreementId);// 協(xié)議id
map.put("nickname",jsBean.getNickname());//用戶姓名
map.put("id_card_no",jsBean.getId_card_no());//身份證號
map.put("mobile",jsBean.getMobile());// 聯(lián)系方式
map.put("province",jsBean.getProvince());// 省
map.put("city",jsBean.getCity());// 市
map.put("country",jsBean.getCountry());// 縣
map.put("address",jsBean.getAddress());//詳細地址
map.put("email",jsBean.getEmail());//郵箱地址
map.put("title",jsBean.getTitle());// 協(xié)議標題
map.put("signed",jsBean.getSigned());
map.put("signed_time",jsBean.getSigned_time());//簽署時間
// map.put("front_id_card",);//身份證正面照鏈接
// map.put("back_id_card",);//身份證反面照鏈接
map.put("agr_type",String.valueOf(agrType));//協(xié)議類型 1:普通協(xié)議 2:隱私協(xié)議
map.put("nper",String.valueOf(nper));//期數(shù)
map.put("nper_upper",jsBean.getNper_upper());//大寫期數(shù)
//本地網(wǎng)絡(luò)請求
myAgreementPresenter.getAgreementDetails(map);
}
}
2. activity_agreement_view.xml 布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:background="@color/color_FFFFFF"
>
<include layout="@layout/layout_title_bar"/>
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_2"
android:progressDrawable="@color/color_FFF96857"
android:visibility="gone"
/>
<com.sumansoul.teacher.widget.custom.CustWebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.sumansoul.teacher.widget.custom.CustWebView>
</LinearLayout>
3. 自定義CustWebView:
public class CustWebView extends WebView {
private OnTouchScreenListener onTouchScreenListener;
public CustWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustWebView(Context context) {
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (onTouchScreenListener != null)
onTouchScreenListener.onTouchScreen();
}
if (event.getAction() == MotionEvent.ACTION_UP) {
if (onTouchScreenListener != null) {
onTouchScreenListener.onReleaseScreen();
}
}
return super.onTouchEvent(event);
}
public interface OnTouchScreenListener {
void onTouchScreen();
void onReleaseScreen();
}
public void setOnTouchScreenListener(OnTouchScreenListener onTouchScreenListener) {
this.onTouchScreenListener = onTouchScreenListener;
}
}
二、總結(jié):
1. 設(shè)置WebView屬性初嘹,能夠執(zhí)行Javascript腳本
mWebView.getSettings().setJavaScriptEnabled(true);//設(shè)置js可用
2. 設(shè)置加載進度條
webview.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
// TODO 自動生成的方法存根
if (newProgress == 100) {
progressBar1.setVisibility(View.GONE);//加載完網(wǎng)頁進度條消失
} else {
progressBar1.setVisibility(View.VISIBLE);//開始加載網(wǎng)頁時顯示進度條
progressBar1.setProgress(newProgress);//設(shè)置進度值
}
}
});
3. 瀏覽器內(nèi)部跳轉(zhuǎn):
/**
* webView 加載的時候 會跳到手機自帶的瀏覽器
* 給自己定義個webview添加客戶端
*/
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
4. webview 顯示點擊返回鍵:
webview.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
//按返回鍵操作并且能回退網(wǎng)頁
if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) {
//后退
webview.goBack();
return true;
}
}
return false;
}
});
5. webview 是否允許調(diào)試:
//允許調(diào)試
if (BuildConfig.DEBUG){
WebView.setWebContentsDebuggingEnabled(true);
}else {
WebView.setWebContentsDebuggingEnabled(false);
}
6. 接受 JS 給 Android 傳遞參數(shù):
在js中調(diào)用本地java方法
webview.addJavascriptInterface(new JsInterface(this), "click");
/**
* 2.編寫一個提供給Web的Js接口類
*/
public class JsInterface {
private Context mContext;
public JsInterface(Context context) {
this.mContext = context;
}
// @JavascriptInterface一定要寫
@JavascriptInterface
public void clickAction(String json, String flag) {
LogUtils.d("LUO", json + "==========" + flag);
ToastUtils.showShort("點擊了按鈕");
}
}
7. Android 給 JS 傳遞參數(shù)
mWebView.loadUrl("javascript:javaCall('fasff')");
頁面加載完成后及汉,給 JS 傳遞參數(shù):
/**
* webView 加載的時候 會跳到手機自帶的瀏覽器
* 給自己定義個webview添加客戶端
*/
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// webview.loadUrl("javascript:loadingDate(' " + mLoginSMSBean.getToken() + " ' ,'" + mAgreementBean.getAgreement_id() + "' ,'" + "2" + "','" + mAgreementBean.getAgr_type() + "','" + mAgreementBean.getNper() + "' ,'" + mAgreementBean.getIs_change() + "' )");
if (!isFirst) {
isFirst = true;
webview.loadUrl("javascript:loadingDate('" + token + "','" + agreementId + "','" + "2" + "','" + agrType + "','" + nper + "','" + isChange + "' )");
// LogUtils.d("LUO", "===" + token);
}
}
});
8. 無法下載文件?
在自己寫的 WebView 下是無法直接下載文件削樊,需要自己監(jiān)聽下載事件并對下載的動作進行處理豁生。
/**
* 當下載文件時打開系統(tǒng)自帶的瀏覽器進行下載,當然也可以對捕獲到的 url 進行處理在應(yīng)用內(nèi)下載漫贞。
**/
webView.setDownloadListener(new FileDownLoadListener());
private class FileDownLoadListener implements DownloadListener {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
作者:cpacm
鏈接:http://www.reibang.com/p/fea5e829b30a
參考鏈接:https://blog.csdn.net/qq_21267961/article/details/79494829