10

我正在尝试创建一个gridview,该gridview 加载了来自驻留在SDCard 上的特定文件夹中的图像。文件夹的路径是已知的 ("/sdcard/pictures") ,但在我在网上看到的示例中,我不确定如何或在哪里指定要从中加载图像的图片文件夹的路径。我已经阅读了几十个教程,甚至是 developer.android.com 上的 HelloGridView 教程,但这些教程并没有教我我在寻找什么。

到目前为止,我读过的每个教程都有:

A)从 /res 文件夹中将图像称为 Drawable 并将它们放入要加载的数组中,根本不使用 SDCard。

B) 使用 MediaStore 访问了 SDCard 上的所有图片,但未指定如何设置我要显示图像的文件夹的路径形式

或者

C) 建议使用 BitmapFactory,我一点也不知道如何使用。

如果我以错误的方式解决这个问题,请让我知道并指导我采用正确的方法来做我想做的事情。

4

6 回答 6

15

好的,经过多次尝试,我终于有了一个可行的例子,我想我会分享它。我的示例查询图像 MediaStore,然后获取每个图像的缩略图以显示在视图中。我正在将图像加载到 Gallery 对象中,但这不是此代码工作的要求:

确保在类级别定义的列索引具有 Cursor 和 int,以便 Gallery 的 ImageAdapter 可以访问它们:

private Cursor cursor;
private int columnIndex;

首先,获取位于文件夹中的图像 ID 光标:

Gallery g = (Gallery) findViewById(R.id.gallery);
// request only the image ID to be returned
String[] projection = {MediaStore.Images.Media._ID};
// Create the cursor pointing to the SDCard
cursor = managedQuery( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        projection, 
        MediaStore.Images.Media.DATA + " like ? ",
        new String[] {"%myimagesfolder%"},  
        null);
// Get the column index of the image ID
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
g.setAdapter(new ImageAdapter(this));

然后,在 Gallery 的 ImageAdapter 中,获取要显示的缩略图:

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView i = new ImageView(context);
    // Move cursor to current position
    cursor.moveToPosition(position);
    // Get the current value for the requested column
    int imageID = cursor.getInt(columnIndex);
    // obtain the image URI
    Uri uri = Uri.withAppendedPath( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(imageID) );
    String url = uri.toString();
    // Set the content of the image based on the image URI
    int originalImageId = Integer.parseInt(url.substring(url.lastIndexOf("/") + 1, url.length()));
    Bitmap b = MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(),
                    originalImageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
    i.setImageBitmap(b);
    i.setLayoutParams(new Gallery.LayoutParams(150, 100));
    i.setScaleType(ImageView.ScaleType.FIT_XY);
    i.setBackgroundResource(mGalleryItemBackground);
    return i;
}

我猜这段代码最重要的部分是 managedQuery,它演示了如何使用 MediaStore 查询来过滤特定文件夹中的图像文件列表。

于 2011-08-23T14:55:07.123 回答
4

您需要执行比 developer.android.com 上的 GridView 教程更多的步骤。使用以下教程 http://developer.android.com/resources/tutorials/views/hello-gridview.html

您需要添加一种方法来从您的 sd 卡创建文件的 ImageView:

创建/添加一个 Vector 到你的类变量(保存一个 ImageViews 列表):

private Vector<ImageView> mySDCardImages;

初始化向量:

mySDCardImages = new Vector<ImageView>();

创建一个加载图像的方法:

List<Integer> drawablesId = new ArrayList<Integer>();
int picIndex=12345;
File sdDir = new File("/sdcard/pictures");
File[] sdDirFiles = sdDir.listFiles();
for(File singleFile : sdDirFiles)
{
   ImageView myImageView = new ImageView(context);
   myImageView.setImageDrawable(Drawable.createFromPath(singleFile.getAbsolutePath());
   myImageView.setId(picIndex);
   picIndex++;
   drawablesId.add(myImageView.getId());
   mySDCardImages.add(myImageView);
}
mThumbIds = (Integer[])drawablesId.toArray(new Integer[0]);

然后在你的 ImageAdapter 方法中,改变

imageView.setImageResource(mThumbIds[position]);

imageView.setImageDrawable(mySDCardImages.get(position).getDrawable());

从 ImageAdapter 中移除 mThumbIds 的初始化。(它应该与 mySDCardImages 的定义一致。两种类方法都可以访问。)

(快速而肮脏的版本)确保测试您的路径等并捕获任何异常。

于 2011-07-22T21:35:06.793 回答
3

在您的情况下,BitmaFactory 可能是一个不错的选择。例子:

File dir = new File( "/sdcard/pictures" );    
String[] fileNames = dir.list(new FilenameFilter() { 
  boolean accept (File dir, String name) {
      if (new File(dir,name).isDirectory())
         return false;
      return name.toLowerCase().endsWith(".png");
  }
});
for(string bitmapFileName : fileNames) {
  Bitmap bmp = BitmapFactory.decodeFile(dir.getPath() + "/" + bitmapFileName);
  // do something with bitmap
}

没有时间对此进行测试,但应该可以工作;-)

于 2011-02-18T10:10:20.230 回答
0

阅读此链接:http
://androidsamples.blogspot.com/2009/06/how-to-display-thumbnails-of-images.html 它展示了如何同时使用 mediastore 和 bitmapfactory。

你应该选择的方式取决于你到底需要什么。如果您有一组静态图像,我认为将它们放在可绘制对象中会更好,因为这样会更快,并且您不依赖可以删除、损坏或文件可以重命名/删除的 sd 卡

如果图像是动态的,则使用 mediastore 或位图工厂。但请记住,将图像放入数组或其他东西非常消耗内存,因此您最终可能会出现内存不足异常

于 2011-02-18T10:10:18.623 回答
0

看起来你想要定制画廊,这对你来说需要很多时间,

我建议您为您的工作获取自定义相机库

您将根据需要在网格视图中获得照片/视频。

于 2015-12-03T09:13:52.127 回答
0

对于 Kotlin 代码,请参阅此问题的答案

这个想法也适用于java(但你需要修改代码)

于 2018-07-07T12:51:27.257 回答