抓住人生中的一分一秒妥箕,勝過虛度中的一月一年!
背景
項目開發(fā)中會經(jīng)常用到webview滥酥,當(dāng)我們每次寫webview時候,都會寫一堆重復(fù)的代碼畦幢,這樣對于高效開發(fā)來說成了累贅坎吻,今天給大家分享一個通用的webview,目的是為了使用簡單化宇葱,本文章實現(xiàn)了webview通用的功能瘦真,如果構(gòu)建復(fù)雜的交互功能刊头,可選擇擴展或者用GitHub一些開源的第三方類庫
實現(xiàn)目標(biāo)
1、webview基本功能實現(xiàn)
2诸尽、進度條實現(xiàn)
說明
為了擴展性高一些原杂,封裝的WebViewWrapper選擇不繼承WebView,而是繼承RelativeLayout您机,在父控件中重新構(gòu)造webview
1穿肄、新建Xml布局,創(chuàng)建webview和ProgressBar
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/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="2dp"
android:progressDrawable="@drawable/progressbar_orange_selector"/>
</RelativeLayout>
2际看、新建WebViewWrapper類咸产,繼承RelativeLayout
public class WebViewWrapper extends RelativeLayout
3、在WebViewWrapper類中創(chuàng)建webview并對其配置屬性
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true); // 默認(rèn)false仿村,設(shè)置true后我們才能在WebView里與我們的JS代碼進行交互
settings.setJavaScriptCanOpenWindowsAutomatically(true); // 設(shè)置JS是否可以打開WebView新窗口
settings.setSupportZoom(true); // 支持縮放
settings.setBuiltInZoomControls(true); // 支持手勢縮放
settings.setDisplayZoomControls(false); // 不顯示縮放按鈕
settings.setDatabaseEnabled(true);//數(shù)據(jù)庫存儲API是否可用锐朴,默認(rèn)值false。
settings.setSaveFormData(true);//WebView是否保存表單數(shù)據(jù)蔼囊,默認(rèn)值true焚志。
settings.setDomStorageEnabled(true);//DOM存儲API是否可用,默認(rèn)false畏鼓。
settings.setGeolocationEnabled(true);//定位是否可用酱酬,默認(rèn)為true。
settings.setAppCacheEnabled(true);//應(yīng)用緩存API是否可用云矫,默認(rèn)值false, 結(jié)合setAppCachePath(String)使用膳沽。
settings.setUseWideViewPort(true); // 將圖片調(diào)整到適合WebView的大小
settings.setLoadWithOverviewMode(true); // 自適應(yīng)屏幕
webView.setHorizontalScrollBarEnabled(false);//去掉webview的滾動條,水平不顯示
webView.setScrollbarFadingEnabled(true);
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setOverScrollMode(View.OVER_SCROLL_NEVER); // 取消WebView中滾動或拖動到頂部、底部時的陰影
4让禀、重新webView方法挑社,對進度條進行監(jiān)聽
private void initListener() {
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return super.shouldOverrideUrlLoading(view, request);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
progressBar.setVisibility(View.GONE);
}
});
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress >= 100) {
progressBar.setVisibility(View.GONE);
} else {
if (progressBar.getVisibility() == View.GONE) {
progressBar.setVisibility(View.VISIBLE);
}
progressBar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
});
}
5、對外開放一些常用的屬性和方法
public void loadUrl(String url) {
mUrl = url;
webView.loadUrl(url);
}
public void setProgressDrawable(@DrawableRes int id) {
progressBar.setProgressDrawable(progressBar.getContext().getResources().getDrawable(id));
}
public WebView getWebView() {
return webView;
}
public String getUrl() {
return mUrl;
}
public boolean goBack() {
if (webView.canGoBack()) {
webView.goBack();
return true;
}
return false;
}
public void onResume() {
webView.getSettings().setJavaScriptEnabled(true);
webView.onResume();
}
public void onPause() {
webView.getSettings().setJavaScriptEnabled(false);
webView.onPause();
}
public void onDestroy() {
webView.setVisibility(GONE);
webView.destroy();
}
下邊介紹下如何使用
<com.yuyaofang.customview.WebViewWrapper
android:id="@+id/webViewWrapper"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@BindView(R.id.webViewWrapper)
WebViewWrapper mWebViewWrapper;
public void getData(String s) {
mWebViewWrapper.loadUrl(s);
}
@Override
public void onResume() {
super.onResume();
mWebViewWrapper.onResume();
}
@Override
public void onPause() {
super.onPause();
mWebViewWrapper.onPause();
}
@Override
public void onDestroy() {
mWebViewWrapper.onDestroy();
super.onDestroy();
}
有網(wǎng)友提出視頻全屏怎么設(shè)置巡揍,封裝類只配置最基本的痛阻,用到了在當(dāng)前頁面擴展,下邊演示下視頻全屏配置
public class EswVideoActivity extends Activity {
@BindView(R.id.back)
LinearLayout mBack;
@BindView(R.id.tv_title)
TextView mTvTitle;
@BindView(R.id.tv_right)
TextView mTvRight;
@BindView(R.id.rlt_base)
RelativeLayout mRltBase;
@BindView(R.id.webview)
WebViewWrapper mWebview;
private CustomViewCallback customViewCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_esw_video);
ButterKnife.bind(this);
mWebview.getWebView().setWebChromeClient(new DefaultWebChromeClient()); // 播放視頻
mWebview.getWebView().loadUrl("http://www.iqiyi.com/fun/20130304/8d2c9f0e9505369e.html");
}
private class DefaultWebChromeClient extends WebChromeClient {
// 進入全屏的時候
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
// 賦值給callback
customViewCallback = callback;
// 設(shè)置webView隱藏
mWebview.getWebView().setVisibility(View.GONE);
// 將video放到當(dāng)前視圖中
mWebview.getFragment().addView(view);
// 橫屏顯示
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// 設(shè)置全屏
setFullScreen();
}
// 退出全屏的時候
@Override
public void onHideCustomView() {
if (customViewCallback != null) {
// 隱藏掉
customViewCallback.onCustomViewHidden();
}
// 用戶當(dāng)前的首選方向
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// 退出全屏
quitFullScreen();
// 設(shè)置WebView可見
mWebview.getWebView().setVisibility(View.VISIBLE);
}
}
/**
* 設(shè)置全屏
*/
private void setFullScreen() {
mRltBase.setVisibility(View.GONE);
// 設(shè)置全屏的相關(guān)屬性腮敌,獲取當(dāng)前的屏幕狀態(tài)阱当,然后設(shè)置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 全屏下的狀態(tài)碼:1098974464
// 窗口下的狀態(tài)嗎:1098973440
}
/**
* 退出全屏
*/
private void quitFullScreen() {
mRltBase.setVisibility(View.VISIBLE);
// 聲明當(dāng)前屏幕狀態(tài)的參數(shù)并獲取
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
getWindow()
.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
// 手機返回鍵監(jiān)聽
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
// 如果是全屏狀態(tài) 按返回鍵則變成非全屏狀態(tài),否則執(zhí)行返回操作
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
quitFullScreen();
} else {
if (mWebview.getWebView().canGoBack()) {
mWebview.getWebView().goBack();
} else {
finish();
}
}
return true;
default:
break;
}
return false;
}
@Override
public void onResume() {
super.onResume();
mWebview.onResume();
}
@Override
public void onPause() {
super.onPause();
mWebview.onPause();
}
@Override
public void onDestroy() {
mWebview.onDestroy();
super.onDestroy();
}
}
全部代碼如下
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import com.yuyaofang.R;
/**
* Created by lp on 2017/2/15.
*/
@SuppressLint("SetJavaScriptEnabled")
public class WebViewWrapper extends RelativeLayout {
private WebView webView;
private ProgressBar progressBar;
private FrameLayout frameLayout;
private String mUrl;
public WebViewWrapper(Context context) {
this(context, null);
}
public WebViewWrapper(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WebViewWrapper(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
initWebViewSettings();
initListener();
}
private void initView(Context context) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.layout_webview, this);
webView = (WebView) view.findViewById(R.id.webView);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
frameLayout = (FrameLayout) view.findViewById(R.id.frameLayout);
}
private void initWebViewSettings() {
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true); // 默認(rèn)false糜工,設(shè)置true后我們才能在WebView里與我們的JS代碼進行交互
settings.setJavaScriptCanOpenWindowsAutomatically(true); // 設(shè)置JS是否可以打開WebView新窗口
settings.setSupportZoom(true); // 支持縮放
settings.setBuiltInZoomControls(true); // 支持手勢縮放
settings.setDisplayZoomControls(false); // 不顯示縮放按鈕
settings.setDatabaseEnabled(true);//數(shù)據(jù)庫存儲API是否可用弊添,默認(rèn)值false。
settings.setSaveFormData(true);//WebView是否保存表單數(shù)據(jù)捌木,默認(rèn)值true油坝。
settings.setDomStorageEnabled(true);//DOM存儲API是否可用,默認(rèn)false。
settings.setGeolocationEnabled(true);//定位是否可用免钻,默認(rèn)為true彼水。
settings.setAppCacheEnabled(true);//應(yīng)用緩存API是否可用,默認(rèn)值false, 結(jié)合setAppCachePath(String)使用极舔。
settings.setUseWideViewPort(true); // 將圖片調(diào)整到適合WebView的大小
settings.setLoadWithOverviewMode(true); // 自適應(yīng)屏幕
webView.setHorizontalScrollBarEnabled(false);//去掉webview的滾動條,水平不顯示
webView.setScrollbarFadingEnabled(true);
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setOverScrollMode(View.OVER_SCROLL_NEVER); // 取消WebView中滾動或拖動到頂部凤覆、底部時的陰影
}
private void initListener() {
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return super.shouldOverrideUrlLoading(view, request);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
progressBar.setVisibility(View.GONE);
}
});
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress >= 100) {
progressBar.setVisibility(View.GONE);
} else {
if (progressBar.getVisibility() == View.GONE) {
progressBar.setVisibility(View.VISIBLE);
}
progressBar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
});
}
public void loadUrl(String url) {
mUrl = url;
webView.loadUrl(url);
}
public void setProgressDrawable(@DrawableRes int id) {
progressBar.setProgressDrawable(progressBar.getContext().getResources().getDrawable(id));
}
public WebView getWebView() {
return webView;
}
public FrameLayout getFragment() {
return frameLayout;
}
public String getUrl() {
return mUrl;
}
public boolean goBack() {
if (webView.canGoBack()) {
webView.goBack();
return true;
}
return false;
}
public void onResume() {
webView.getSettings().setJavaScriptEnabled(true);
webView.onResume();
}
public void onPause() {
webView.getSettings().setJavaScriptEnabled(false);
webView.onPause();
}
public void onDestroy() {
webView.setVisibility(GONE);
webView.destroy();
}
}
進度條樣式如下
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<gradient
android:endColor="@color/colorTransparent"
android:startColor="@color/colorTransparent"/>
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<gradient
android:endColor="@color/colorAccent"
android:startColor="@color/colorPrimary"/>
</shape>
</clip>
</item>
</layer-list>
最后,祝大家開發(fā)順利!