如何使用图像目录中的单个图像表示文件来实现图像库
Posted
技术标签:
【中文标题】如何使用图像目录中的单个图像表示文件来实现图像库【英文标题】:How to implement Image gallery with single image representing file in image directory 【发布时间】:2021-11-21 21:55:33 【问题描述】:我正在尝试实现 Instagram 或 WhatsApp 之类的功能,其中存在于 android 文件夹中的单个图像的缩略图显示在列表项的顶部,更像是图像类型的示例文件夹。
帮助我了解此功能。
【问题讨论】:
我不太明白你的问题,但我想你想知道如何在另一个布局上显示布局,但下面的布局仍然可见,对吗?如果这是您想要实现的目标,请不要在上面的布局上放置背景颜色。如果您在style.xml
或theme.xml
中设置了android:windowBackground
,那么您可能需要删除它或在上面的布局中设置android:background="#000000"
。 #000000
表示透明色。
我不是说喜欢。我的意思是 Instagram 保存功能。您可以在目录顶部看到已保存的帖子预览。
你想实现一个图片库还是什么?目录中存在的单张照片位于图像目录的顶部
是的,是的。我不知道怎么称呼它
【参考方案1】:
我是如何实现它的。虽然它可能不是最好的,但它确实有效。
我使用MediaStore获取了所有图片的URI,你可以学习如何使用它here。
第一步是在后台线程中完成的,以防止它阻塞 UI 线程。
我整理了我得到的图像,将它们分组到 List<Image>
中,这将代表一个目录。
然后我将List<Image>
添加到List<List<Image>>
中,作为获取的整体图像并具有它们的总大小,我稍后使用它来跟踪目录中的图像数量。
代码如下。
@Override
public void run()
Uri storageUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
storageUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
else
storageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
// the queries to the MediaStore API (The image details or metadata I need
String[] projection =
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.SIZE,
MediaStore.Images.Media.DISPLAY_NAME;
// now query the MediaStore API using ContentResolver
Cursor imgCursor = getApplicationContext().getContentResolver().query(storageUri, projection, null, null, null);
int bucketId = imgCursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
int imgSize = imgCursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
int name = imgCursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
int bucketName = imgCursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
// directoryDictionary is a temporary list of directory names that was found, while querying the MediaStore API
List<String> directoryDictionary = new ArrayList<>();
// generalList is just a list that would represent a general image list, where all images can be found. Just like Whatsapp
List<Image> generalList = new ArrayList<>();
while (imgCursor.moveToNext())
long id = imgCursor.getLong(bucketId);
int size = imgCursor.getInt(imgSize);
String fileName = imgCursor.getString(name);
String folderName = imgCursor.getString(bucketName);
// As recommended by the Android developers doc
Uri contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
// a single image
Image currentImage = new Image(contentUri, size, fileName, folderName);
// add all images to the general image list, but modifying the directory name
Image genImage = new Image(contentUri, size, fileName, "All Media");
generalList.add(genImage);
int directoryIndex = CollectionUtils.linearSearch(directoryDictionary, folderName);
// if search result (directoryIndex) passes this test, then it means that there is
// no such directory in list of directory names
if (directoryIndex < 0)
imageDirectoryList.add(new ArrayList<>());
directoryDictionary.add(folderName);
directoryIndex = CollectionUtils.linearSearch(directoryDictionary, folderName);
if (directoryIndex >= 0)
imageDirectoryList.get(directoryIndex).add(currentImage);
else
imageDirectoryList.get(directoryIndex).add(currentImage);
//...then add it if the image list of folder is > 2
if (imageDirectoryList.size() > 2) imageDirectoryList.add(0, generalList);
imgCursor.close();
runOnUiThread(() ->
// imageAdapter is the RecyclerView's list Adapter.
// notifyDataSetChanged() must be call to refresh list.
imageAdapter.notifyDataSetChanged();
// doViewUpdate was just used to turn on and off the visibility of some views
doViewUpdate();
);
【讨论】:
以上是关于如何使用图像目录中的单个图像表示文件来实现图像库的主要内容,如果未能解决你的问题,请参考以下文章