从GridView中的SD卡目录加载图像

时间:2011-12-30 05:16:08

标签: android image gridview storage sd-card

我创建了一个应用程序,允许用户在外部存储上创建相册(文件夹)。现在我试图从所述目录中检索图像并将它们显示在GridView中。我正在使用AsyncTask使用listFiles()遍历文件目录,然后在抓取每个图像后再创建一个位图,然后重新使用它。我的问题是我的GridView中没有出现任何内容。我已经设置了一些Log break,LogCat告诉我迭代确实发生了并且检索了图像。这让我觉得我在我的Adapter类中的某个地方犯了一个错误,它将位图绑定到Grid,可能在getView中?或者也许我错了。对我做错的任何帮助?我试图尽可能地评论代码,但我遗漏了不必要的部分。感谢

public class AlbumGridView extends Activity implements OnItemClickListener {

private GridView sdcardImages;
private ImageAdapter imageAdapter;

private Display display;

private Bitmap bitmap;
private Bitmap b;

File[] imageList;
private static final String TAG = "AlbumGridView";
String path;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    setContentView(R.layout.album_view);

    //display = 
    //((Object) getSystemService(Context.WINDOW_SERVICE))).getDefaultDisplay();

    path = getIntent().getStringExtra("key");
    Toast.makeText(this, path, Toast.LENGTH_SHORT).show();
    setupViews();
    setProgressBarIndeterminateVisibility(true);
    loadImages();



}

protected void onDestroy() {
    super.onDestroy();
    final GridView grid = sdcardImages;
    final int count = grid.getCount();
    ImageView v = null;
    for (int i = 0; i < count; i++) {
        v = (ImageView) grid.getChildAt(i);
        ((BitmapDrawable) v.getDrawable()).setCallback(null);
    }
}

// Set up the GridView

private void setupViews() {
    sdcardImages = (GridView) findViewById(R.id.gvAlbumView);
    // sdcardImages.setNumColumns(display.getWidth()/95);
    sdcardImages.setClipToPadding(false);
    sdcardImages.setOnItemClickListener(AlbumGridView.this);
    imageAdapter = new ImageAdapter(getApplicationContext());
    // imageAdapter.setImageList(path);
    sdcardImages.setAdapter(imageAdapter);
}

private void addImage(LoadedImage... value) {
    for (LoadedImage image : value) {
        imageAdapter.addPhoto(image);
        imageAdapter.notifyDataSetChanged();
    }
}

// Save Bitmap images to a list and return that list
@Override
public Object onRetainNonConfigurationInstance() {
    final GridView grid = sdcardImages;
    final int count = grid.getChildCount();
    final LoadedImage[] list = new LoadedImage[count];

    for (int i = 0; i < count; i++) {
        final ImageView v = (ImageView) grid.getChildAt(i);
        list[i] = new LoadedImage(
                ((BitmapDrawable) v.getDrawable()).getBitmap());
    }

    return list;
}

private void loadImages() {
    // TODO Auto-generated method stub
    final Object data = getLastNonConfigurationInstance();
    if (data == null) {
        new LoadImagesFromSDCard().execute();
    } else {
        final LoadedImage[] photos = (LoadedImage[]) data;
        if (photos.length == 0) {
            new LoadImagesFromSDCard().execute();
        }
        for (LoadedImage photo : photos) {
            addImage(photo);
        }
    }
}

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
    // TODO Auto-generated method stub

}

/ ------------------------------------------- ------------------------------------------ /

//Adapter for the GridView

public class ImageAdapter extends BaseAdapter {

    private Context mContext;
    private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();

    private String path;
    private Bitmap bitmap;

    public ImageAdapter(Context context) {
        mContext = context;
    }

    public void addPhoto(LoadedImage photo) {
        photos.add(photo);
    }

    public int getCount() {
        return photos.size();
    }

    public Object getItem(int position) {
        return photos.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    /*
     * public File[] setImageList(String path) {
     * 
     * //this.path = path; //this.imageList = imageList; //File imagesDir =
     * new File(path); //imageList = imagesDir.listFiles();
     * 
     * File imagesDir = new File(path); imageList = imagesDir.listFiles();
     * for (File image : imageList) try { bitmap =
     * BitmapFactory.decodeStream(image.toURL().openStream()); //use bitmap
     * and recycle afterwards LoadedImage lm = new LoadedImage(bitmap);
     * this.addPhoto(lm); bitmap.recycle();
     * 
     * } catch (IOException e) { e.printStackTrace(); } return imageList;
     * 
     * }
     */

    public View getView(int position, View convertView, ViewGroup parent) {
        final ImageView imageView;
        if (convertView == null) {
            imageView = new ImageView(mContext);
        } else {
            imageView = (ImageView) convertView;
        }
        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageView.setPadding(2, 2, 2, 2);
        // imageView.setImageBitmap(photos.get(position).getBitmap());
        try {
            imageView
                    .setImageBitmap(BitmapFactory
                            .decodeStream(imageList[position].toURL()
                                    .openStream()));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return imageView;
    }
}

/*-------------------------------------------------------------------------*/

//AsyncTask to get the images

class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {

    @Override
    protected Object doInBackground(Object... arg0) {
        // Load images from SD card in Background
        // Display each image on the screen

        File imagesDir = new File(path);
        imageList = imagesDir.listFiles();

        for (File image : imageList)

            try {

                if (bitmap != null) {
                    bitmap.recycle();
                    bitmap = null;
                }
                bitmap = BitmapFactory.decodeStream(image.toURL()
                        .openStream());
                Log.e(TAG, "Grabbed Image " + image.getName());
                // use bitmap then recycle after

                LoadedImage lm = new LoadedImage(bitmap);
                // addImage(lm);
                // imageAdapter.addPhoto(lm);
                // imageAdapter.setImageList(path);
                // imageAdapter.addPhoto(lm);
                // imageAdapter.setImageList(path);
                // bitmap.recycle();
                // addImage(lm);
                // imageAdapter.addPhoto(lm);
                Log.e(TAG, "Added Image " + lm.toString());

                // imageAdapter.setImageList(path);
                addImage(lm);

                // bitmap.recycle();

                // bitmap.recycle();

            } catch (Exception e) {
                e.printStackTrace();
            }

        return null;
    }

1 个答案:

答案 0 :(得分:1)

这是解决方案顺便说一句,对不起,我花了很长时间才意识到其他人都在等待答案。抱歉。相关代码如下。

这是AsyncTask,它将查询设备的MediaStore并检索所有照片。请注意,这是检索缩略图而不是全尺寸图像,更具体地说,它是MICRO_KIND。还有一个Thumbnail.MINI_KIND。

/*----------------------------ASYNC TASK TO LOAD THE     PHOTOS--------------------------------------------------------*/

public class LoadPhotos extends AsyncTask<Object, Object, Object> {

    @Override
    protected Object doInBackground(Object... params) {
        try {
            final String[] columns = { MediaStore.Images.Media._ID };
            final String orderBy = MediaStore.Images.Media._ID;

            Cursor imagecursor = managedQuery(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
                    null, null, orderBy);

            int image_column_index = imagecursor
                    .getColumnIndex(MediaStore.Images.Media._ID);

            AllPhotosActivity.count = imagecursor.getCount();
            AllPhotosActivity.windows = new Bitmap[AllPhotosActivity.count];

            for (int i = 0; i < AllPhotosActivity.count; i++) {
                imagecursor.moveToPosition(i);
                // i = index;
                int id = imagecursor.getInt(image_column_index);
                windows[i] = MediaStore.Images.Thumbnails.getThumbnail(
                        getApplicationContext().getContentResolver(), id,
                        MediaStore.Images.Thumbnails.MICRO_KIND, null);
            }

            imagecursor.close();
        } catch (Exception e) {
            e.printStackTrace();
            Log.d("AllPhotosActivity",
                    "Error occured while fetching all photos on device.");
        }
        return null;

    }

    @Override
    protected void onPostExecute(Object result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        Handler mHandler = new Handler();

        mHandler.post(new Runnable() {

            public void run() {

                pd.dismiss();
                // imageAdapter.notifyDataSetChanged();
                // sdcardImages.setAdapter(imageAdapter);

            }

        });

        // pd.dismiss();
        imagegrid.setAdapter(imageAdapter);
        // pd.dismiss();

    }

    @Override
    protected void onProgressUpdate(Object... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
    }

}

这是GridView的适配器,它将缩略图绑定到gridview。我的问题只是在我的ImageAdapter的getView方法中,注意我是从Bitmaps数组的不同索引设置我的ImageView资源我称之为windows。

public class ImageAdapter extends BaseAdapter {
    private Context mContext;

    public ImageAdapter(Context c) {
        mContext = c;
    }

    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView i = (ImageView) convertView;
        if (i != null) {
            i.setImageBitmap(windows[position]);
        } else {
            i = new ImageView(mContext.getApplicationContext());
            // i.setPadding(3, 3, 3, 3);
            // i.setScaleType(ImageView.ScaleType.FIT_CENTER);
            i.setAdjustViewBounds(true);
            // i.setMaxHeight(200);
            // i.setMaxWidth(200);
            i.setPadding(3, 3, 3, 3);
            i.setLayoutParams(new GridView.LayoutParams(92, 92));
            i.setImageBitmap(windows[position]);

        }
        return i;
    }

    public int getCount() {
        // TODO Auto-generated method stub
        return count;
    }
}