This is an image viewer which support multiple images, where only one image is shown at any time, where you can swipe to navigate.
ImageFragment
NOTE: I am using Jetpack Navigation, thus I am using a Fragment instead of Activity.
class ImageFragment : Fragment() { // private val viewModel: ImageViewModel by viewModels() private lateinit var adapter: LocalAdapter private val args: ImageFragmentArgs by navArgs() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.image, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) init() } private fun init() { adapter = LocalAdapter(viewModel) viewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL viewPager.adapter = adapter val items = args.default.items?.map { ViewItem.ImageItem(id = it.id, date = it.date, uri = it.uri, content = it.content) } adapter.submitList(items) args.default.position?.also { position -> viewPager.doOnLayout { viewPager.currentItem = position } } } sealed class ViewItem(open val id: String, val resource: Int) { data class ImageItem(override val id: String, val date: LocalDateTime, val uri: Uri, val content: String?) : ViewItem(id, R.layout.image_item) } class LocalAdapter(val viewModel: ImageViewModel): ListAdapter<ViewItem, LocalAdapter.ViewHolder>(DiffCallback()) { override fun getItemViewType(position: Int): Int { return getItem(position).resource } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(viewType, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = getItem(position) when(item) { is ViewItem.ImageItem -> { bindImage(holder, item) } } } private fun bindImage(holder: ViewHolder, item: ViewItem.ImageItem) { holder.apply { imageTextView.text = item.date.toString() imageDraweeView.setImageURI(item.uri) val lines = listOf( item.id, item.date.toString(), item.content ).filter { it?.isEmpty() == false } imageTextView.text = lines.joinToString("\n") } } private class DiffCallback : DiffUtil.ItemCallback<ViewItem>() { override fun areItemsTheSame(oldItem: ViewItem, newItem: ViewItem): Boolean { if (oldItem.resource != newItem.resource) return false // check if id is the same return oldItem.id == newItem.id } @SuppressLint("DiffUtilEquals") override fun areContentsTheSame(oldItem: ViewItem, newItem: ViewItem): Boolean { // check if content is the same // equals using data class return oldItem == newItem } } inner class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer { } }}
NOTE: For zoomable image, refer to Zoomable PhotoView With Glide or ZoomableDraweeView
ImageArgs
@Parcelizeclass ImageArgs(val items: List<Item>? = null, val position: Int): Parcelable { @Parcelize class Item(val id: String, val date: LocalDateTime, val uri: Uri, val content: String?): Parcelable}
NOTE: Refer to Jetpack Navigation
image.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.support.ImageFragment">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
image_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/imageDraweeView"
android:layout_width="match_parent"
android:layout_height="match_parent"
fresco:actualImageScaleType="fitCenter"
fresco:placeholderImage="@drawable/placeholder_100"
/>
<TextView
android:id="@+id/imageTextView"
tools:text="Hello"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#fff"
android:shadowColor="#000"
android:shadowDx="2"
android:shadowDy="2"
android:shadowRadius="1.5"
/>
</FrameLayout>
Usage
val images = mutableListOf<ImageArgs.Item>()// get image// item = ...var position = 0images.add(ImageArgs.Item(id = item.id, uri = item.uri, date = item.date, content = item.content))// refer to jetpack navigationval args = ImageArgs(items = images, position = position)val action = BatchFragmentDirections.actionBatchNavToImageNav(args)findNavController().navigate(action)