最近在适配小米8.0的时候 , 发现WebView无法加载本地的文件 . 以下是个人通过自定义WebView解决的代码 , 以供参考:
public class WebViewSuite extends RelativeLayout {
private Context context;
public static final int PROGRESS_BAR_STYLE_NONE = 0;
public static final int PROGRESS_BAR_STYLE_LINEAR = 1;
public static final int PROGRESS_BAR_STYLE_CIRCULAR = 2;
//attributes
private int progressBarStyle = PROGRESS_BAR_STYLE_LINEAR;
private int inflationDelay = 100;
private boolean enableJavaScript = true;
private boolean overrideTelLink = true;
private boolean overrideEmailLink = true;
private boolean overridePdfLink = true;
private boolean showZoomControl = false;
private boolean enableVerticalScrollBar = false;
private boolean enableHorizontalScrollBar = false;
private String url;
private String htmlData;
private String mimeType;
private String encoding;
private ViewStub webViewStub;
private WebView webView;
private ProgressBar linearProgressBar;
private ProgressBar circularProgressBar;
private ProgressBar customProgressBar;
private boolean webViewInflated = false;
private WebViewSuiteCallback callback;
private WebViewSetupInterference interference;
private WebViewOpenPDFCallback openPDFCallback;
public WebViewSuite(@NonNull Context context) {
super(context);
init(context);
}
public WebViewSuite(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.WebViewSuite, 0, 0);
try {
progressBarStyle = a.getInt(R.styleable.WebViewSuite_webViewProgressBarStyle, PROGRESS_BAR_STYLE_LINEAR);
inflationDelay = a.getInt(R.styleable.WebViewSuite_inflationDelay, 100);
enableJavaScript = a.getBoolean(R.styleable.WebViewSuite_enableJavaScript, true);
overrideTelLink = a.getBoolean(R.styleable.WebViewSuite_overrideTelLink, true);
overrideEmailLink = a.getBoolean(R.styleable.WebViewSuite_overrideEmailLink, true);
overridePdfLink = a.getBoolean(R.styleable.WebViewSuite_overridePdfLink, true);
showZoomControl = a.getBoolean(R.styleable.WebViewSuite_showZoomControl, false);
enableVerticalScrollBar = a.getBoolean(R.styleable.WebViewSuite_enableVerticalScrollBar, false);
enableHorizontalScrollBar = a.getBoolean(R.styleable.WebViewSuite_enableHorizontalScrollBar, false);
url = a.getString(R.styleable.WebViewSuite_url);
} finally {
a.recycle();
}
init(context);
}
public WebViewSuite(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
this.context = context;
View rootView = inflate(context, R.layout.web_view_suite, this);
webViewStub = (ViewStub) rootView.findViewById(R.id.webview_stub);
linearProgressBar = (ProgressBar) rootView.findViewById(R.id.linear_progressbar);
circularProgressBar = (ProgressBar) rootView.findViewById(R.id.circular_progressbar);
switch (progressBarStyle) {
case PROGRESS_BAR_STYLE_CIRCULAR:
linearProgressBar.setVisibility(GONE);
circularProgressBar.setVisibility(VISIBLE);
break;
case PROGRESS_BAR_STYLE_NONE:
linearProgressBar.setVisibility(GONE);
circularProgressBar.setVisibility(GONE);
break;
case PROGRESS_BAR_STYLE_LINEAR:
default:
circularProgressBar.setVisibility(GONE);
linearProgressBar.setVisibility(VISIBLE);
}
Handler webViewInflationHandler = new Handler();
webViewInflationHandler.postDelayed(new Runnable() {
@Override
public void run() {
webView = (WebView) webViewStub.inflate();
webViewInflated = true;
postWebViewInflated();
}
}, inflationDelay);
}
private void postWebViewInflated () {
if (!webViewInflated || webView == null) return;
setupWebView();
if (url != null && !url.isEmpty()) {
webView.loadUrl(url);
} else if (htmlData != null && !htmlData.isEmpty()) {
webView.loadData(htmlData, mimeType, encoding);
}
}
/**
* @des 加载url
* @param url
*/
public void startLoading (String url) {
this.url = url;
if (!webViewInflated || webView == null) return;
webView.loadUrl(url);
}
public void startLoadData (String data, String mimeType, String encoding) {
this.htmlData = data;
this.mimeType = mimeType;
this.encoding = encoding;
if (!webViewInflated || webView == null) return;
webView.loadData(htmlData, mimeType, encoding);
}
public boolean goBackIfPossible () {
if (webView != null && webView.canGoBack()) {
webView.goBack();
return true;
} else {
return false;
}
}
/**
* @des 刷新webview
*/
public void refresh () {
if (webView != null) webView.reload();
}
/**
* @des 设置进度条
* @param progressBar
*/
public void setCustomProgressBar (ProgressBar progressBar) {
this.customProgressBar = progressBar;
}
public void toggleProgressbar (boolean isVisible) {
int status = isVisible ? View.VISIBLE : View.GONE;
switch (progressBarStyle) {
case PROGRESS_BAR_STYLE_CIRCULAR:
circularProgressBar.setVisibility(status);
break;
case PROGRESS_BAR_STYLE_NONE:
if (customProgressBar != null) customProgressBar.setVisibility(status);
break;
case PROGRESS_BAR_STYLE_LINEAR:
default:
linearProgressBar.setVisibility(status);
}
}
public void customizeClient (WebViewSuiteCallback callback) {
this.callback = callback;
}
public void interfereWebViewSetup (WebViewSetupInterference interference) {
this.interference = interference;
}
public void setOpenPDFCallback (WebViewOpenPDFCallback callback) {
this.openPDFCallback = callback;
}
public WebView getWebView () {
return this.webView;
}
public ProgressBar getProgressBar (int progressBarStyle) {
return progressBarStyle == PROGRESS_BAR_STYLE_LINEAR ? linearProgressBar : circularProgressBar;
}
private void setupWebView () {
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
toggleProgressbar(true);
if (callback != null) callback.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
toggleProgressbar(false);
if (callback != null) callback.onPageFinished(view, url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("tel:") && overrideTelLink) {
try {
Intent telIntent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
context.startActivity(telIntent);
return true;
} catch (Exception e) {
return false;
}
} else if (url.startsWith("mailto:") && overrideEmailLink) {
try {
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:")); // only email apps should handle this
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{url.substring(7)});
if (emailIntent.resolveActivity(context.getPackageManager()) != null) {
context.startActivity(emailIntent);
}
return true;
} catch (Exception e) {
return false;
}
} else if (url.endsWith("pdf") && overridePdfLink) {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
if (openPDFCallback != null) openPDFCallback.onOpenPDF();
return true;
} else {
if (callback != null) {
return callback.shouldOverrideUrlLoading(webView, url);
} else {
return super.shouldOverrideUrlLoading(view, url);
}
}
}
});
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
super.onGeolocationPermissionsShowPrompt(origin, callback);
}
});
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(enableJavaScript);
webSettings.setBuiltInZoomControls(showZoomControl);
webView.setVerticalScrollBarEnabled(enableVerticalScrollBar);
webView.setHorizontalScrollBarEnabled(enableHorizontalScrollBar);
if (interference != null) interference.interfereWebViewSetup(webView);
}
public interface WebViewSuiteCallback {
void onPageStarted(WebView view, String url, Bitmap favicon);
void onPageFinished(WebView view, String url);
boolean shouldOverrideUrlLoading(WebView view, String url);
}
public interface WebViewSetupInterference {
void interfereWebViewSetup(WebView webView);
}
public interface WebViewOpenPDFCallback {
void onOpenPDF();
}
}
以上是个人解决8.0WebView无法加载本地文件的解决方案 , 在各个手机上适配 , 发现是可以显示加载的本地内容 . 如果对代码有什么疑问 , 欢迎指正或留言.