【发布时间】:2015-03-23 02:51:19
【问题描述】:
我正在关注此Android tutorial 以修复在我的GridView 中使用Bitmap 图像时不断出现的“内存不足”错误。本教程解决了这个问题,但是现在当我单击活动中的其他选项卡时,然后返回到我的照片选项卡,那里的照片会翻倍。例如,当我第一次加载选项卡时,它会从我的 SD 卡中提取 3 张照片,并用占位符图像填充其余部分。但是当我浏览其他标签(总共 4 个)时,我回来在我的照片标签 GridView 中找到 6 张图片,其余的都是占位符。
背景信息:每次我的标签可见时,它都会从 SD 卡加载图像,将它们更改为位图,然后我的适配器将这些图像放入 GridView 内的每个 ImageView 中。在我遇到内存问题之前,它加载得很好,当我浏览其他选项卡然后回到照片选项卡时,它没有加倍图像。然而,它最终确实因内存问题而崩溃,所以我不得不修复它。
如何在刷新标签时不加载双倍?感谢您的帮助。
PhotoTab.java
package org.azurespot.cutecollection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import org.azurespot.R;
import java.io.File;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class PhotoTab extends Fragment {
private GridView gridView;
File[] files;
ArrayList<PhotoGridItem> photoList = new ArrayList<>();
ArrayAdapter<PhotoGridItem> adapter;
Bitmap bitmap;
public PhotoTab() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.photo_tab, container, false);
// with fragments, make sure you include the rootView when finding id
gridView = (GridView) v.findViewById(R.id.photo_grid);
adapter = new GridViewPhotoAdapter(getActivity(), R.layout.photo_grid_item);
// Set the Adapter to GridView
gridView.setAdapter(adapter);
adapter.addAll(loadSDCard());
// add the default icons remaining, to GridView, if less than 24 files on SD card
for (int i = 0; i < (24 - photoList.size()); i++) {
adapter.add(new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder)));
}
adapter.notifyDataSetChanged();
return v;
}
private ArrayList<PhotoGridItem> loadSDCard() {
try {
// gets directory CutePhotos from sd card
File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), "CutePhotos");
// lists all files in CutePhotos, loads in Files[] array
files = cutePhotosDir.listFiles();
for (File singleFile : files) {
String filePath = singleFile.getAbsolutePath();
bitmap = decodeSampledBitmap(filePath, 270, 270);
photoList.add(new PhotoGridItem(bitmap));
}
} catch (Exception e) {
e.printStackTrace();
}
return photoList;
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmap(String path, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
}
GridViewPhotoAdapter
package org.azurespot.cutecollection;
/**
* Created by mizu on 2/5/15.
*/
// package org.azurespot.cutecollection;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.azurespot.R;
/**
* Created by mizu on 2/5/15.
*/
public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {
public Context context;
private int resourceId;
Bitmap bm;
public GridViewPhotoAdapter(Context context, int layoutResourceId) {
super(context, layoutResourceId);
this.context = context;
this.resourceId = layoutResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
final ViewHolder holder;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(resourceId, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) row.findViewById(R.id.photo_grid_view);
// stores holder with view
row.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
PhotoGridItem photoGridItem = getItem(position);
if (photoGridItem != null) {
bm = photoGridItem.getImage();
holder.imageView.setImageBitmap(bm);
// positioning the image in the GridView slot
holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.imageView.setLayoutParams(new LinearLayout.LayoutParams
(270, 270));
}
return row;
}
public class ViewHolder{
ImageView imageView;
}
}
【问题讨论】:
标签: android bitmap android-gridview android-sdcard android-memory