КОДЕКС

Android Simple Image Gallery

Создание простого приложения для создания галереи изображений на Android

На каждом устройстве Android есть приложение галереи, в котором хранятся все изображения и видео устройства. В этом посте я покажу, как вы можете создать собственное приложение для создания базовой галереи изображений. Код доступен на GitHub.

Этот пост будет разделен на три части. В первой мы увидим, как получить доступ ко всем изображениям на внешнем хранилище устройства и отобразить RecyclerView с элементами, представляющими папки, в которых есть хотя бы один файл изображения, в во второй части мы реализуем прослушиватель кликов по элементам для каждого элемента папки, чтобы каждый раз, когда вы нажимали на один из элементов, появлялось новое действие и отображало все изображения в этой папке в RecyclerView и, наконец, третью часть будет состоять из создания браузера изображений, чтобы иметь возможность просматривать изображения, перемещая их в ViewPager и используя горизонтальный RecyclerView как PagerIndicator, конечный результат можно увидеть в gif ниже.

Часть 1

Чтение внешнего хранилища изображений

Чтобы создать нашу галерею, нам нужно получить доступ к внешнему хранилищу устройства и получить все изображения, для этого нам нужно разрешение на чтение внешнего хранилища, для этого добавьте следующую строку в свой AndroidManifest.xml.

Android MediaStore

Затем мы собираемся использовать Android MediaStore для чтения внешнего хранилища изображений. Если вы не знаете, что такое MediaStore, прочтите эту документацию. Чтобы упростить задачу, MediaStore можно рассматривать как базу данных, в которой хранятся все мультимедийные файлы на вашем устройстве, такие как музыкальные файлы, изображения и видео. Он автоматически индексирует каждый мультимедийный файл, добавленный в хранилище устройства.

Примечание: из-за обновлений в Android SDK, которые повлияли на MediaStore и сделали MediaStore.Images.Media. DATA устаревшим, обновление раздел добавлен в эту статью внизу

Ниже приведено основное действие, и я добавил повсюду комментарии, чтобы объяснить, что происходит в каждом методе, основным методом, который следует здесь отметить, является метод getPicturePaths (), он использует поставщика мультимедиа, чтобы получить все папки с изображениями и возвращает ArrayList объекта imageFolder, который является классом для хранения данных папки изображений.

imageFolder.java

Часть 2

MainActivity реализует интерфейс itemClickListener, который используется для обеспечения связи между Activity и pictureFolderAdapter. Это поможет нам прослушивать клики по каждому элементу в pictureFolderAdapter RecyclerView с помощью onPicClicked (String pictureFolderPath, String folderName) слушателя, как вы можете видеть, он принимает два параметра: путь к папке, к которой был нажат элемент папки в представлении ресайклера, и имя папки it, которое затем используется для откройте намерение для действия ImageDisplay, которое будет использовать эту информацию для вывода списка всех изображений в этой папке.

itemClickListener.java

pictureFolderAdapter

ниже показан результат MainActivity, каждый элемент в recyclerview представляет папку с изображениями и количество изображений, которые она содержит.

Часть 3

Вероятно, это будет самая длинная часть этой публикации. Мы собираемся углубиться в работу отображения изображений Activity и pictureBrowserFragment, так что давайте сделаем это.

Действие ImageDisplay также реализует наш itemClickListener, чтобы взаимодействовать с элементами изображения picture_Adapter нашего recyclerview. В методе действия onCreate мы начинаем с инициализации всех необходимых представлений в XML-файле макета действий, так как действие доступно только для Intent из MainActivity, мы используем это Intent для получения пути папки, из которой мы будем получать изображения и отображать, строки кода ниже показывают, что

затем путь к папке используется в качестве параметра в методе getAllImagesByFolder () для получения всех изображений в этой папке, метод возвращает ArrayList pictureFacer, который является классом, содержащим информации об изображении, этот ArrayList затем используется для создания нашего picture_Adapter и устанавливает его в Recyclerview, который будет отображать все изображения в этой папке на экране.

pictureFacer класс

picture_Adapter

если вы посмотрите на метод onBindViewHolder объекта picture_Adapter, вы обнаружите, что в конце onClickListener установлен на imageView для держателя просмотра, это означает, что каждый раз, когда вы нажимаете на изображение, метод onPicClicked () в picListener выполняется с тремя параметрами.

Holder: viewHolder изображения, по которому только что щелкнули.

poistion: позиция ViewHolder в списке элементов.

список изображений: список всех изображений.

Эти три параметра будут использоваться для создания экземпляра pictureBrowserFragment для просмотра изображений в viewPager, это можно увидеть в методе onPicClicked () действия ImageDisplay ниже.

Слайдер изображений

Как видно из метода onPicClicked ImageDisplay Activity, при щелчке по изображению создается новый экземпляр pictureBrowserFragment, передавая параметры, как указано выше, holder, position, pictureList.

Параметр Holder здесь не очень полезен, но может использоваться для включения анимации перехода между общими представлениями, то есть ImageView в ViewHolder и соответствующим imageView на странице объекта PictureBrowserFragment ViewPager.

pictureList - это ArrayList для pictureFacer, и он используется в pictureBrowserFragment для построения страниц viewPager, где на каждой странице отображается соответствующее изображение, соответствующее ее положению, pictureList также используется для создания imageIndicator RecyclerView.

Параметр position будет использоваться в pictureBrowserFragment для отображения текущей или начальной страницы ViewPager, эта позиция соответствует положению изображения, на котором был выполнен щелчок. действие ImageDisplay.

imageIndicator RecyclerView: imageIndicator RecyclerView - это горизонтальный recyclerView в нижней части pictureBrowserFragment, который используется для навигации между изображениями в ViewPager.

В методе onViewCreated () объекта pictureBrowserFragment мы сначала инициализируем представления и ImagesPagerAdapter для ViewPager, а затем imageIndicatorRecyclerView также устанавливается с помощью indicatorAdapter, приведенный ниже код хорошо прокомментирован для понимания всего, что происходит в этом фрагменте.

pictureBrowserFragment

IndicatorAdapter

при всей этой настройке у нас должен быть результат ниже, вы можете получить проект на Github

Обновлять

Прежде чем продолжить чтение, вы должны были заметить, что код для получения ваших изображений из MediaStore длинный и в некотором роде сложный, чтобы облегчить вашу жизнь, я приглашаю вас использовать библиотеку классов MediaFacer для получения всего вашего мультимедийного контента из MediaStore.

Библиотека MediaFacer предназначена для помощи в структурированных запросах к MediaStore для получения медиафайлов самым простым способом с учетом обоих носителей информации на устройстве, то есть внутреннего и внешнего хранилища. устройства, прочтите статью ниже, чтобы узнать больше о MediaFacer

Https://android.jlelse.eu/handling-media-files-with-mediafacer-library-for-android-cd9d2ca0dc68

С момента публикации этой статьи в Android Apis были внесены некоторые обновления и изменения, и это также коснулось объектов MediaStore, на данный момент с выходом Android 10 MediaStore.Images.Media. DATA и MediaStore.Images.ImageColumns. DATA устарели, эти переменные изначально использовались разработчиками для прямого доступа к медиафайлу на носители данных устройства, используя java.io.File api, но многие вещи изменились с выпуском Android 10 (уровень Api 29 или Q), java .io.file api игнорируется, и для выполнения любых операций с файлами необходимо использовать Android Storage Access Framework, который был представлен в Android 4.4 (уровень Api 19 или Kitkat) и на данный момент, чтобы использовать api java.io.file в вашем проекте Android, вы должны установить android: requestLegacyExternalStorage в приложении Applicat ion файла Manifest.xml вашего Android-устройства на значение True.

Возвращаясь к нашей проблеме с Mediastore, мы больше не будем использовать MediaStore.Images.Media. DATA для получения прямого доступа к файлу, но мы будем создавать Uri, который я вызову ContentUri, который предоставит нам прямой доступ к медиафайлу, чтобы получить этот uri, нам нужно использовать MediaStore.Images.Media. EXTERNAL_CONTENT_URI или MediaStore.Images.Media. INTERNAL_CONTENT_URI для внутреннего содержания и MediaStore.Images.Media. _ID самого медиафайла, если вы загрузили проект на Github и просмотрели код, то вы уже знаете, как получить эти переменные для создания нашего ContentUri просто используйте фрагмент кода ниже

int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
Uri contentUri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id));

затем вы можете использовать этот ContentUri для доступа к медиафайлу с помощью объекта AssertFileDescriptor

try {
    AssetFileDescriptor file = context.getContentResolver().openAssetFileDescriptor(contentUri, "r");
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

вы также можете использовать ContentUri напрямую для загрузки изображения в ImageView с помощью Glide

ImageView picture = findViewById(R.id.picture);
Glide.with(context)
        .load(contentUri)
        .apply(new RequestOptions().placeholder(R.drawable.ic_mediafacer).centerCrop())
        .into(picture);

Я буду обновлять код на github и счастливого кодирования.