您的位置:首页 > 移动开发

[置顶] Android使用WebView加载图片防止OutOfMemoryError

2013-10-28 16:45 477 查看


分类:
Android总结 2013-06-09 16:01
571人阅读
评论(0)
收藏
举报

AndroidWebView加载图片OutOfMemoryErrorAndroid大图片

在Android中, 大图片加载或者处理很容易出来OutOfMemory,也就是内存溢出

所以在这里就使用WebView来加载大图片,但是WebView不好控制图片显示大小,也就是说

如果图片太大,webview将出一滚动条,图片过小则不可拉伸,极其影响美观。为此,作了些

修改,在一定区域内做一些图片尺寸的压缩。

主要实现方式:由WebView的父控件居中布局来控制垂直方向的居中,WebView的元素居中

来控制图片的水平居中 ,最终达到图片在屏幕的中间显示。

核心Java代码如下:

[java]
view plaincopyprint?

private void showImageByWebView(String path){
webViewLayout = (LinearLayout) findViewById(R.id.img_webview);
webView = new WebView(this);

String url = "file://"+ path;

int[] wh = new int[2];
int disenty;//屏幕密度
WindowManager wManager = this.getWindowManager();
DisplayMetrics disM = new DisplayMetrics();
wManager.getDefaultDisplay().getMetrics(disM);
disM = this.getResources().getDisplayMetrics();
disenty = disM.disenty;
wh[0] = dis.widthPixels;
Rect outRect = new Rect();
webViewLayout.getWindowVisibleDisplayFrame(outRect); //获取状态栏高度
int contentHeight = (int) (wh[1] - this.getResources().getDimension(R.dimen.title_height) - outRect.top - 30); //获取webview应该显示的高度,屏幕高度减去标题栏高度和状态栏高度

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options); // 因为设置了inJustDecodeBounds=true 所以此时返回的 bitmap 为 null,仅取出bitmap的信息,而不把它读到内存
options.inJustDecodeBounds = false;

int bitmapWidth = options.outWidth;
int bitmapHeight = options.outHeight;

String style = "";
int[] imgDis = new int[2];
int minHeight = getResources().getDimensionPixelSize(R.dimen.loadview_img_minheight);

//注;由于webview将会设置settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);表示单列所以宽度适应内容大小,所以宽度大于屏幕而高度小于屏幕时不需要再压缩
if(bitmapHeight > (float)contentHeight/disenty){
double scale = 0.00f;
scale = (double)contentHeight / bitmapHeight;
imgDis[0] = (int) (scale * bitmapWidth / (disenty + 0.1));//这里加上了0.1的原因与以上减30一样,webview宽高肯定大于图片内容所显示的宽度,里面还会有padding属性
imgDis[1] = (int) (scale * bitmapHeight / (disenty + 0.1));
style = "style=\"width: " + imgDis[0] + "px; height: " + imgDis[1] + "px;\"";
}else if(bitmapHeight < minHeight){
double scale = (double)minHeight/bitmapHeight ;
int width = (int) (scale * bitmapWidth);
style = "style=\"width: " + width / disenty + "px; height: " + minHeight / disenty + "px;\"";
}

StringBuffer data = new StringBuffer();
data.append("<html><center><img src=\"")
.append(url)
.append("\" ")
.append(style)
.append("></center></html>");

webView.loadDataWithBaseURL(url, data.toString(), "text/html","UTF-8","");
webView.setScrollContainer(false);
webView.setScrollbarFadingEnabled(false);

WebSettings settings = webView.getSettings();
settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
settings.setBuiltInZoomControls(false); // 设置显示缩放按钮
settings.setSupportZoom(true); //支持缩放
//webView.setInitialScale(100);

// settings.setUseWideViewPort(true); //双击放大,但是在这里如果放大将会有问题
// settings.setLoadWithOverviewMode(true);//多窗口预览方式显示

webView.setBackgroundColor(0x00000000);

// View zoomControls = webView.getZoomControls();
// LayoutParams paramszoom = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
// zoomControls.setLayoutParams(paramszoom);

LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.CENTER);
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
webView.setMinimumHeight(500);
webViewLayout.addView(webView, params);
}

private void showImageByWebView(String path){
webViewLayout = (LinearLayout) findViewById(R.id.img_webview);
webView = new WebView(this);

String url = "file://"+ path;

int[] wh = new int[2];
int disenty;//屏幕密度
WindowManager wManager = this.getWindowManager();
DisplayMetrics  disM = new DisplayMetrics();
wManager.getDefaultDisplay().getMetrics(disM);
disM = this.getResources().getDisplayMetrics();
disenty = disM.disenty;
wh[0] = dis.widthPixels;
Rect outRect = new Rect();
webViewLayout.getWindowVisibleDisplayFrame(outRect); //获取状态栏高度
int contentHeight = (int) (wh[1] - this.getResources().getDimension(R.dimen.title_height) - outRect.top - 30); //获取webview应该显示的高度,屏幕高度减去标题栏高度和状态栏高度

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options); // 因为设置了inJustDecodeBounds=true 所以此时返回的 bitmap 为 null,仅取出bitmap的信息,而不把它读到内存
options.inJustDecodeBounds = false;

int bitmapWidth = options.outWidth;
int bitmapHeight = options.outHeight;

String style = "";
int[] imgDis = new int[2];
int minHeight = getResources().getDimensionPixelSize(R.dimen.loadview_img_minheight);

//注;由于webview将会设置settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);表示单列所以宽度适应内容大小,所以宽度大于屏幕而高度小于屏幕时不需要再压缩
if(bitmapHeight > (float)contentHeight/disenty){
double scale = 0.00f;
scale = (double)contentHeight / bitmapHeight;
imgDis[0] = (int) (scale * bitmapWidth / (disenty + 0.1));//这里加上了0.1的原因与以上减30一样,webview宽高肯定大于图片内容所显示的宽度,里面还会有padding属性
imgDis[1] = (int) (scale * bitmapHeight / (disenty + 0.1));
style = "style=\"width: " + imgDis[0] + "px; height: " + imgDis[1] + "px;\"";
}else if(bitmapHeight < minHeight){
double scale = (double)minHeight/bitmapHeight ;
int width = (int) (scale * bitmapWidth);
style = "style=\"width: " + width / disenty + "px; height: " + minHeight / disenty + "px;\"";
}

StringBuffer data = new StringBuffer();
data.append("<html><center><img src=\"")
.append(url)
.append("\" ")
.append(style)
.append("></center></html>");

webView.loadDataWithBaseURL(url, data.toString(), "text/html","UTF-8","");
webView.setScrollContainer(false);
webView.setScrollbarFadingEnabled(false);

WebSettings settings = webView.getSettings();
settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
settings.setBuiltInZoomControls(false); // 设置显示缩放按钮
settings.setSupportZoom(true); //支持缩放
//webView.setInitialScale(100);

// settings.setUseWideViewPort(true); //双击放大,但是在这里如果放大将会有问题
// settings.setLoadWithOverviewMode(true);//多窗口预览方式显示

webView.setBackgroundColor(0x00000000);

//		View zoomControls = webView.getZoomControls();
//		LayoutParams paramszoom = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
//		zoomControls.setLayoutParams(paramszoom);

LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.CENTER);
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
webView.setMinimumHeight(500);
webViewLayout.addView(webView, params);
}


核心布局代码如下:

[html]
view plaincopyprint?

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- .....--> <LinearLayout android:id="@+id/img_webview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerInParent="true" android:minHeight="200dip" android:minWidth="200dip" android:gravity="center" android:paddingTop="@dimen/title_normal_height" /> </RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<!-- .....-->

<LinearLayout
android:id="@+id/img_webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:minHeight="200dip"
android:minWidth="200dip"
android:gravity="center"
android:paddingTop="@dimen/title_normal_height"
/>

</RelativeLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐