【问题标题】:Displaying images from a specific folder on the SDCard using a gridview使用网格视图显示来自 SDCard 上特定文件夹的图像
【发布时间】:2011-06-29 17:08:01
【问题描述】:

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

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

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

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

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

如果我以错误的方式处理此问题,请告诉我并指导我采用正确的方法来做我想做的事情。

【问题讨论】:

    标签: android gridview uri android-sdcard bitmapfactory


    【解决方案1】:

    好的,经过多次尝试,我终于有了一个可行的示例,我想我会分享它。我的示例查询图像 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 查询来过滤特定文件夹中的图像文件列表。

    【讨论】:

    • 感谢您的样品 :)
    • @achilldress :您好,我完全按照您的代码进行操作。但我记录 columnIndex 为 0,cursor 不为空。好像错了,你知道为什么吗?请告诉我。谢谢。
    • 我从索引 0 得到的 imageID 为空。 android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
    • managedQuery 现在已被弃用,并且由于未知原因,此处的光标始终为空。
    【解决方案2】:

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

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

    为您的类变量创建/添加一个 Vector(以保存 ImageView 列表):

    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 的定义一致。两种类方法都可以访问。)

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

    【讨论】:

    • 嗨,我使用了developer.android.com/guide/topics/ui/layout/… 这个,我想改变它来从 SDCard 获取文件。你能告诉我你的代码在哪里写吗?谢谢
    • 如果您想将其作为问题发布,我会回答。我不知道我可以在这里的评论中很好地回答这个问题。
    【解决方案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
    }
    

    没有时间测试这个但应该可以工作;-)

    【讨论】:

    • 感谢evilcroco的回复,我正在测试你的代码!
    【解决方案4】:

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

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

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

    【讨论】:

    • 感谢您的回复!我已经按照教程进行了正确编译,但是在更改从中加载图像的文件夹路径时遇到了麻烦。但是,我确实在 cmets 中读过,您可以更改文件夹路径查询。我的问题是:我会在“imagecursor = managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, img, null, null, MediaStore.Images.Thumbnails.IMAGE_ID + "");" 处更改查询吗?它是否接受字符串作为参数?
    【解决方案5】:

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

    我建议您为您的工作获取Custom Camera Gallery

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

    【讨论】:

      【解决方案6】:

      对于 Kotlin 代码,请参阅question 的答案

      思想也适用于java(但需要修改代码)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-14
        相关资源
        最近更新 更多