本文主要学习自网上各路大神后做的笔记、Demo,现整理至CSDN博客,主要有鸿洋_、郭霖、Carson_Ho、aqi00 等大神。
1.要点
一个可视为浏览器的View
用于加载html页面及处理交互
重量级View,建议在代码中添加至布局内存角度
建议至于独立Activity且占满
2.使用
2.1布局文件
不在布局文件中直接引入使用,使用java代码添加WebView,便于管控其生命周期
< LinearLayoutxmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:orientation= "vertical">
< include
layout= "@layout/app_toolbar_base"
/>
< LinearLayout
android:id= "@+id/h5_content_layout"
android:orientation= "vertical"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:paddingTop= "8dp"
>
LinearLayout>
LinearLayout>
2.2Java代码添加WebView
//
LinearLayout mContentLayout;
WebView mWebView;
@ Override
protectedvoidonCreate( @Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_h5);
initToolbar;
initView; //初始化控件
initData;
}
privatevoidinitView( ){
mContentLayout = findViewById(R.id.h5_content_layout);
LinearLayout.LayoutParams params= newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
//代码中添加WebView
mWebView = newWebView( this.getApplicationContext);
mWebView.setLayoutParams( params);
mContentLayout.addView(mWebView);
//配置WebView
buildWebView;
}
2.3 控制生命周期,防止内存泄漏
//
@Override
protectedvoidonNewIntent(Intent intent){
super.onNewIntent(intent);
setIntent(intent);
}
@SuppressLint( "SetJavaEnabled")
@Override
protectedvoidonResume{
super.onResume;
mWebView.getSettings.setJavaEnabled( true);
}
@Override
protectedvoidonPause{
dismissLoading;
mWebView.getSettings.setJavaEnabled( false);
super.onPause;
}
@Override
protectedvoidonDestroy{
destoryWebView;
dismissLoading;
super.onDestroy;
}
privatevoiddestoryWebView{
if(mWebView != null) {
//加载空页面,并清理缓存、历史
mWebView.loadDataWithBaseURL( null, "", "text/html", "utf-8", null);
mWebView.clearHistory;
mWebView.clearCache( true);
//移除、释放
((ViewGroup) mWebView.getParent).removeView(mWebView);
mWebView.destroy;
mWebView = null;
}
}
privatevoiddismissLoading{
}
2.4 重点:WebView 配置
privatevoidbuildWebView{
mWebView.setWebChromeClient( newWebChromeClient{
@Override
publicvoidonReceivedTitle(WebView view, String title){
if(!TextUtils.isEmpty(title)){
if(title.length< 6){
mToolbarTitle.setText(title);
} elseif(title.length> 10){
mToolbarTitle.setTextSize( 12f);
title = title.substring( 0, 8);
title = title + "...";
mToolbarTitle.setText(title);
} else{
mToolbarTitle.setTextSize( 14f);
mToolbarTitle.setText(title);
}
}
}
});
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mWebView.getSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
mWebView.setWebViewClient( newWebViewClient {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
publicbooleanshouldOverrideUrlLoading(WebView view, WebResourceRequest request){
view.loadUrl(String.valueOf(request.getUrl), request.getRequestHeaders);
returntrue;
}
@Override
publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed;
}
@Override
publicvoidonPageStarted(WebView view, String url, Bitmap favicon){
showLoading;
}
@Override
publicvoidonPageFinished(WebView view, String url){
dismissLoading;
}
});
} else{
mWebView.setWebViewClient( newWebViewClient {
@Override
publicbooleanshouldOverrideUrlLoading(WebView view, String url){
view.loadUrl(url);
returntrue;
}
@Override
publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed;
}
@Override
publicvoidonPageStarted(WebView view, String url, Bitmap favicon){
showLoading;
}
@Override
publicvoidonPageFinished(WebView view, String url){
dismissLoading;
}
});
}
//设置
WebSettings webSettings = mWebView.getSettings;
//设置支持Java
webSettings.setJavaEnabled( true);
//设置自适应
webSettings.setUseWideViewPort( true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode( true); // 缩放至屏幕的大小
//缩放
webSettings.setSupportZoom( true); //支持缩放,默认为true。是setBuiltInZoomControls(true)的前提。
webSettings.setBuiltInZoomControls( true); //设置内置的缩放控件。若为false=不可缩放
webSettings.setDisplayZoomControls( false); //隐藏原生的缩放控件
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//缓存模式如下:
//LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
//LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
//LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
//LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
webSettings.setAllowFileAccess( true); //可以访问文件
webSettings.setDomStorageEnabled( true); // 开启DOM storage
webSettings.setDatabaseEnabled( true); //开启database storage
webSettings.setAppCacheEnabled( true); //开启Application Caches
String cacheDirPath = getFilesDir.getAbsolutePath + APP_CACAHE_DIRNAME;
webSettings.setAppCachePath(cacheDirPath); //设置Caches缓存目录
//每个 Application 只调用一次 WebSettings.setAppCachePath,WebSettings.setAppCacheMaxSize
webSettings.setJavaCanOpenWindowsAutomatically( true); //通过JS打开新窗口
webSettings.setLoadsImagesAutomatically( true); //自动加载图片
webSettings.setDefaultTextEncodingName( "utf-8"); //设置编码格式
}
3.其他细节代码
载入页面
privatevoidloadH5( ){
if(TextUtils.isEmpty(mUrlStr)){
return;
}
//先清理,后载入,减小内存占用
mWebView.loadDataWithBaseURL( null, "", "text/html", "utf-8", null);
mWebView.clearHistory;
mWebView.clearCache( true);
mWebView.loadUrl(mUrlStr);
}
AndroidManifest.xml声明权限
< uses-permissionandroid:name= "android.permission.INTERNET"/>
AndroidManifest.xml声明H5Activity
< activity
android:name= ".H5Activity"
android:screenOrientation= "portrait"/>
res/values/style.xml
< stylename= "AppTheme"parent= "Theme.AppCompat.Light.NoActionBar">
< itemname= "colorPrimary">@color/colorPrimary item>
< itemname= "colorPrimaryDark">@color/colorPrimaryDark item>
< itemname= "colorAccent">@color/colorAccent item>
style>
4.完整Activity代码
packagecom.cupster.webview;
importandroid.annotation.SuppressLint;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.graphics.Bitmap;
importandroid.graphics.Color;
importandroid.net.http.SslError;
importandroid.os.Build;
importandroid.os.Bundle;
importandroid.support.annotation.Nullable;
importandroid.support.annotation.RequiresApi;
importandroid.support.v7.app.AppCompatActivity;
importandroid.support.v7.widget.Toolbar;
importandroid.text.TextUtils;
importandroid.util.Log;
importandroid.view.KeyEvent;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.webkit.SslErrorHandler;
importandroid.webkit.WebChromeClient;
importandroid.webkit.WebResourceRequest;
importandroid.webkit.WebSettings;
importandroid.webkit.WebView;
importandroid.webkit.WebViewClient;
importandroid.widget.ImageView;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
importstaticandroid.view.KeyEvent.KEYCODE_BACK;
publicclassH5ActivityextendsAppCompatActivity{
privatestaticfinalString TAG = "H5Activity";
privatestaticfinalString APP_CACAHE_DIRNAME = "/didigoweb";
publicstaticfinalString KEY_H5_URL = "H5_URL";
TextView mToolbarTitle;
LinearLayout mContentLayout;
WebView mWebView;
String mUrlStr;
booleanisCanScale = true;
publicstaticvoidopen(Context context , String url){
Intent intent = newIntent(context , H5Activity.class);
intent.putExtra(KEY_H5_URL ,url);
context.startActivity(intent);
}
@Override
protectedvoidonCreate(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
View decorView = getWindow.getDecorView;
intoption = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
getWindow.setStatusBarColor(Color.WHITE);
} else{
}
setAndroidNativeLightStatusBar( this, true);
setContentView(R.layout.activity_h5);
initToolbar;
initView;
initData;
}
@SuppressLint( "SetJavaEnabled")
@Override
protectedvoidonResume{
super.onResume;
mWebView.getSettings.setJavaEnabled( true);
}
@Override
protectedvoidonPause{
dismissLoading;
mWebView.getSettings.setJavaEnabled( false);
super.onPause;
}
@Override
protectedvoidonDestroy{
destoryWebView;
dismissLoading;
super.onDestroy;
}
@Override
protectedvoidonNewIntent(Intent intent){
super.onNewIntent(intent);
setIntent(intent);
}
publicbooleanonKeyDown( intkeyCode, KeyEvent event){
if((keyCode == KEYCODE_BACK) && mWebView.canGoBack) {
finish;
returntrue;
}
returnsuper.onKeyDown(keyCode, event);
}
privatevoidinitToolbar{
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle( "");
toolbar.setBackgroundColor(getResources.getColor(R.color.white));
setSupportActionBar(toolbar);
ImageView back = findViewById(R.id.toolbar_back_left);
back.setOnClickListener( newView.OnClickListener {
@Override
publicvoidonClick(View v){
finish;
}
});
ImageView scale = findViewById(R.id.toolbar_icon_msg);
scale.setImageResource(R.mipmap.icon_web_scale);
scale.setVisibility(View.VISIBLE);
scale.setOnClickListener( newView.OnClickListener {
@Override
publicvoidonClick(View v){
isCanScale = !isCanScale;
if(isCanScale){
((ImageView)v).setImageResource(R.mipmap.icon_web_scalable);
mWebView.getSettings.setSupportZoom( true); //支持缩放,默认为true。是下面那个的前提。
mWebView.getSettings.setBuiltInZoomControls( true); //设置内置的缩放控件。若为false,则该WebView不可缩
} else{
((ImageView)v).setImageResource(R.mipmap.icon_web_scale);
mWebView.getSettings.setSupportZoom( false); //支持缩放,默认为true。是下面那个的前提。
mWebView.getSettings.setBuiltInZoomControls( false); //设置内置的缩放控件。若为false,则该WebView不可缩
}
loadH5;
}
});
mToolbarTitle = findViewById(R.id.toolbar_title);
mToolbarTitle.setTextColor(getResources.getColor(R.color.text_black));
mToolbarTitle.setTextSize( 16.0f);
mToolbarTitle.setText( "详情");
}
privatevoidinitView{
mContentLayout = findViewById(R.id.h5_content_layout);
LinearLayout.LayoutParams params = newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mWebView = newWebView( this.getApplicationContext);
mWebView.setLayoutParams(params);
mContentLayout.addView(mWebView);
buildWebView;
}
privatevoidinitData{
if(getIntent == null){
finish;
return;
}
mUrlStr = getIntent.getStringExtra(KEY_H5_URL);
if( TextUtils.isEmpty(mUrlStr) || "null".equals(mUrlStr) ){
finish;
return;
}
loadH5;
}
privatevoidloadH5{
if(TextUtils.isEmpty(mUrlStr)){
return;
}
mWebView.loadDataWithBaseURL( null, "", "text/html", "utf-8", null);
mWebView.clearHistory;
mWebView.clearCache( true);
mWebView.loadUrl(mUrlStr);
}
privatevoidbuildWebView{
mWebView.setWebChromeClient( newWebChromeClient{
@Override
publicvoidonReceivedTitle(WebView view, String title){
if(!TextUtils.isEmpty(title)){
if(title.length< 6){
mToolbarTitle.setText(title);
} elseif(title.length> 10){
mToolbarTitle.setTextSize( 12f);
title = title.substring( 0, 8);
title = title + "...";
mToolbarTitle.setText(title);
} else{
mToolbarTitle.setTextSize( 14f);
mToolbarTitle.setText(title);
}
}
}
});
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mWebView.getSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
mWebView.setWebViewClient( newWebViewClient {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
publicbooleanshouldOverrideUrlLoading(WebView view, WebResourceRequest request){
view.loadUrl(String.valueOf(request.getUrl), request.getRequestHeaders);
returntrue;
}
@Override
publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed;
}
@Override
publicvoidonPageStarted(WebView view, String url, Bitmap favicon){
showLoading;
}
@Override
publicvoidonPageFinished(WebView view, String url){
dismissLoading;
}
});
} else{
mWebView.setWebViewClient( newWebViewClient {
@Override
publicbooleanshouldOverrideUrlLoading(WebView view, String url){
view.loadUrl(url);
returntrue;
}
@Override
publicvoidonReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed;
}
@Override
publicvoidonPageStarted(WebView view, String url, Bitmap favicon){
showLoading;
}
@Override
publicvoidonPageFinished(WebView view, String url){
dismissLoading;
}
});
}
//设置
WebSettings webSettings = mWebView.getSettings;
//设置支持Java
webSettings.setJavaEnabled( true);
//设置自适应
webSettings.setUseWideViewPort( true); //将图片调整到适合webview的大小
webSettings.setLoadWithOverviewMode( true); // 缩放至屏幕的大小
//缩放
webSettings.setSupportZoom( true); //支持缩放,默认为true。是setBuiltInZoomControls(true)的前提。
webSettings.setBuiltInZoomControls( true); //设置内置的缩放控件。若为false=不可缩放
webSettings.setDisplayZoomControls( false); //隐藏原生的缩放控件
//其他细节操作
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//缓存模式如下:
//LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
//LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
//LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
//LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
webSettings.setAllowFileAccess( true); //可以访问文件
webSettings.setDomStorageEnabled( true); // 开启DOM storage
webSettings.setDatabaseEnabled( true); //开启database storage
webSettings.setAppCacheEnabled( true); //开启Application Caches
String cacheDirPath = getFilesDir.getAbsolutePath + APP_CACAHE_DIRNAME;
webSettings.setAppCachePath(cacheDirPath); //设置Caches缓存目录
//每个 Application 只调用一次 WebSettings.setAppCachePath,WebSettings.setAppCacheMaxSize
webSettings.setJavaCanOpenWindowsAutomatically( true); //通过JS打开新窗口
webSettings.setLoadsImagesAutomatically( true); //自动加载图片
webSettings.setDefaultTextEncodingName( "utf-8"); //设置编码格式
}
privatevoidshowLoading{
}
//
privatevoiddestoryWebView{
if(mWebView != null) {
mWebView.loadDataWithBaseURL( null, "", "text/html", "utf-8", null);
mWebView.clearHistory;
mWebView.clearCache( true);
((ViewGroup) mWebView.getParent).removeView(mWebView);
mWebView.destroy;
mWebView = null;
}
}
privatevoiddismissLoading{
}
protectedstaticvoidsetAndroidNativeLightStatusBar(Activity activity, booleandark){
View decor = activity.getWindow.getDecorView;
if(dark) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else{
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
}
5.完整代码 ,copy即用
github: https://github.com/Cupster/OneDayOneView/tree/master/webview
感谢:
鸿洋_、郭霖、Carson_Ho、aqi00 等大神
原文作者:Cupster
原文链接:https://blog.csdn.net/Cupster/article/details/104289177