使用gridview在SDCard上显示来自特定文件夹的图像

时间:2021-10-26 00:21:22

I'm attempting to create a gridview that is loaded with images from a specific folder that resides on an SDCard. The path to the folder is known, ("/sdcard/pictures") , but in the examples I've seen online I am unsure how or where to specify the path to the pictures folder I want to load images from. I have read through dozens of tutorials, even the HelloGridView tutorial at developer.android.com but those tutorials do not teach me what i am seeking.

我正在尝试创建一个gridview,其中装载来自SDCard上特定文件夹的图像。文件夹的路径是已知的(“/sdcard/pictures”),但在我在网上看到的示例中,我不确定如何或在哪里指定要从pictures文件夹加载图像的路径。我读过很多教程,甚至是developer.android.com网站上的HelloGridView教程,但是这些教程并没有告诉我我想要什么。

Every tutorial I have read so far has either:

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

A) called the images as a Drawable from the /res folder and put them into an array to be loaded, not using the SDCard at all.

A)将图像作为/res文件夹的可绘制文件调用,并将其放入要加载的数组中,而不使用SDCard。

B) Accessed all pictures on the SDCard using the MediaStore but not specifying how to set the path to the folder I want to display images form

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

or

C) Suggested using BitmapFactory, which I haven't the slightest clue how to use.

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

If I'm going about this in the wrong way, please let me know and direct me toward the proper method to do what I'm trying to do.

如果我以错误的方式处理这件事,请让我知道并指导我正确的方法去做我想做的事情。

6 个解决方案

#1


15  

OK, after many iterations of trying, I finally have an example that works and I thought I'd share it. My example queries the images MediaStore, then obtains the thumbnail for each image to display in a view. I am loading my images into a Gallery object, but that is not a requirement for this code to work:

好吧,经过多次尝试,我终于有了一个行之有效的例子,我想我应该分享一下。我的示例查询图像MediaStore,然后获取要在视图中显示的每个图像的缩略图。我正在将我的图像加载到一个Gallery对象中,但是这并不是这个代码工作的必要条件:

Make sure you have a Cursor and int for the column index defined at the class level so that the Gallery's ImageAdapter has access to them:

确保在类级定义了列索引的游标和int,以便画廊的ImageAdapter能够访问它们:

private Cursor cursor;
private int columnIndex;

First, obtain a cursor of image IDs located in the folder:

首先,获取位于文件夹中的图像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));

Then, in the ImageAdapter for the Gallery, obtain the thumbnail to display:

然后,在图片库的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;
}

I guess the most important section of this code is the managedQuery that demonstrates how to use MediaStore queries to filter a list of image files in a specific folder.

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

#2


4  

You need to do a few more steps than the GridView tutorial on developer.android.com. Using the following tutorial http://developer.android.com/resources/tutorials/views/hello-gridview.html

您需要做更多的步骤,而不是在developer.android.com上的GridView教程。使用以下教程http://developer.android.com/resources/tutorials/views/hello-gridview.html

You'll want to add a method to create ImageView's of the files from your sd card:

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

Create/add a Vector to your class variables (to hold a list of ImageViews):

创建/添加一个向量到您的类变量中(用于保存ImageViews列表):

private Vector<ImageView> mySDCardImages;

Initialize the vector:

初始化向量:

mySDCardImages = new Vector<ImageView>();

Create a method to load images:

创建加载图像的方法:

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]);

Then down in your ImageAdapter method, change

然后在ImageAdapter方法中,更改

imageView.setImageResource(mThumbIds[position]);

to

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

Remove from the ImageAdapter the initialization of mThumbIds. (it should be up with the definition of mySDCardImages. Accessible to both class methods.)

从ImageAdapter删除mthumbid的初始化。(这应该与mySDCardImages的定义相符。可以同时访问两个类方法。

(Quick and dirty version) Make sure to test your path, etc and catch any Exceptions.

(快速和下流的版本)确保测试您的路径,等等,并捕获任何异常。

#3


3  

In your case BitmaFactory might be a good way to go. Example:

就你的情况而言,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
}

Not time to test this but should work ;-)

不是测试这个而是应该工作的时候;-)

#4


0  

read this link: http://androidsamples.blogspot.com/2009/06/how-to-display-thumbnails-of-images.html
it shows how to use both mediastore and bitmapfactory.

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

the way you should chose depends on what exactly you need. if you have a static set of images, it's much better idea to put them to drawables, i think, cause this way it's faster and you don't rely on sd card, which can be removed, corrupt or files could be renamed/deleted

你应该选择的方式取决于你到底需要什么。如果你有一组静态的图像,最好把它们放到drawables,因为这样更快,而且你不需要sd卡,它可以删除、损坏或者文件可以重命名/删除

if images are dynamic, then use mediastore or bitmap factory. but keep in mind that putting images into array or something it's quite memory consuming, so you can end up having outofmemory exception

如果图像是动态的,那么使用mediastore或位图工厂。但是请记住,将图像放入数组或其他一些非常消耗内存的东西中,所以您最终可能会遇到outofmemory异常

#5


0  

Looks like you want custom gallerry, it will take much time for you,

看起来你想要自定义的法国人,这需要很多时间,

I suggest you get Custom Camera Gallery for your working.

我建议你为你的工作找一个自定义的摄影画廊。

You will get Photos/Videos in Grid View as you want.

你将得到你想要的照片/视频。

#6


0  

for Kotlin code see the answer of this question

关于Kotlin代码,请参见这个问题的答案

the idea is alslo applicable for java (but you need to modify the code)

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

#1


15  

OK, after many iterations of trying, I finally have an example that works and I thought I'd share it. My example queries the images MediaStore, then obtains the thumbnail for each image to display in a view. I am loading my images into a Gallery object, but that is not a requirement for this code to work:

好吧,经过多次尝试,我终于有了一个行之有效的例子,我想我应该分享一下。我的示例查询图像MediaStore,然后获取要在视图中显示的每个图像的缩略图。我正在将我的图像加载到一个Gallery对象中,但是这并不是这个代码工作的必要条件:

Make sure you have a Cursor and int for the column index defined at the class level so that the Gallery's ImageAdapter has access to them:

确保在类级定义了列索引的游标和int,以便画廊的ImageAdapter能够访问它们:

private Cursor cursor;
private int columnIndex;

First, obtain a cursor of image IDs located in the folder:

首先,获取位于文件夹中的图像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));

Then, in the ImageAdapter for the Gallery, obtain the thumbnail to display:

然后,在图片库的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;
}

I guess the most important section of this code is the managedQuery that demonstrates how to use MediaStore queries to filter a list of image files in a specific folder.

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

#2


4  

You need to do a few more steps than the GridView tutorial on developer.android.com. Using the following tutorial http://developer.android.com/resources/tutorials/views/hello-gridview.html

您需要做更多的步骤,而不是在developer.android.com上的GridView教程。使用以下教程http://developer.android.com/resources/tutorials/views/hello-gridview.html

You'll want to add a method to create ImageView's of the files from your sd card:

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

Create/add a Vector to your class variables (to hold a list of ImageViews):

创建/添加一个向量到您的类变量中(用于保存ImageViews列表):

private Vector<ImageView> mySDCardImages;

Initialize the vector:

初始化向量:

mySDCardImages = new Vector<ImageView>();

Create a method to load images:

创建加载图像的方法:

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]);

Then down in your ImageAdapter method, change

然后在ImageAdapter方法中,更改

imageView.setImageResource(mThumbIds[position]);

to

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

Remove from the ImageAdapter the initialization of mThumbIds. (it should be up with the definition of mySDCardImages. Accessible to both class methods.)

从ImageAdapter删除mthumbid的初始化。(这应该与mySDCardImages的定义相符。可以同时访问两个类方法。

(Quick and dirty version) Make sure to test your path, etc and catch any Exceptions.

(快速和下流的版本)确保测试您的路径,等等,并捕获任何异常。

#3


3  

In your case BitmaFactory might be a good way to go. Example:

就你的情况而言,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
}

Not time to test this but should work ;-)

不是测试这个而是应该工作的时候;-)

#4


0  

read this link: http://androidsamples.blogspot.com/2009/06/how-to-display-thumbnails-of-images.html
it shows how to use both mediastore and bitmapfactory.

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

the way you should chose depends on what exactly you need. if you have a static set of images, it's much better idea to put them to drawables, i think, cause this way it's faster and you don't rely on sd card, which can be removed, corrupt or files could be renamed/deleted

你应该选择的方式取决于你到底需要什么。如果你有一组静态的图像,最好把它们放到drawables,因为这样更快,而且你不需要sd卡,它可以删除、损坏或者文件可以重命名/删除

if images are dynamic, then use mediastore or bitmap factory. but keep in mind that putting images into array or something it's quite memory consuming, so you can end up having outofmemory exception

如果图像是动态的,那么使用mediastore或位图工厂。但是请记住,将图像放入数组或其他一些非常消耗内存的东西中,所以您最终可能会遇到outofmemory异常

#5


0  

Looks like you want custom gallerry, it will take much time for you,

看起来你想要自定义的法国人,这需要很多时间,

I suggest you get Custom Camera Gallery for your working.

我建议你为你的工作找一个自定义的摄影画廊。

You will get Photos/Videos in Grid View as you want.

你将得到你想要的照片/视频。

#6


0  

for Kotlin code see the answer of this question

关于Kotlin代码,请参见这个问题的答案

the idea is alslo applicable for java (but you need to modify the code)

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