Why Not! Image Carousel! Version 2 released! It’s time for an Infinite Carousel!

Md. Mahmudul Hasan Shohag
4 min readMay 22, 2021
Photo by freddie marriage from Unsplash

Why Not! Image Carousel! Version 2 released! 😃 In this post, I will discuss some of the new features and some challenges I face during coding it.

What’s new in version 2?

There are many new features, changes, and modifications that come with version 2. Notable features/changes are —

  1. Custom view with View Binding support.
  2. Infinite carousel support.
  3. Touch-to-pause support.
  4. Carousel view gravity added so that the view can be aligned from start.
  5. ImageCarousel is now a lifecycle-aware component.
  6. More use cases and inspiring samples were added.

The full release note can be found here. Let’s discuss some of the features.

Custom view with View Binding support

The age of findViewById() is long gone, now View-Binding is the recommended way for handling/accessing views. So we removed the old custom layout system and added View-Binding supported custom layout system. It’s straightforward. Example code:

For Java example see the readme of the library. Here we just inflate the view and bind the view with data like the implementation of the RecyclerView Adapter. So simple isn’t it! 😎

Custom View with no ImageView

Using the custom view you can use the carousel without any image. For this, you can use blank CarouselItem objects. See the samples for an example like this.

♾ Infinite carousel support

Infinite Carousel

The library now supports item looping, which we called an infinite carousel. This feature currently is the default for the carousel. If you need you can disable it by setting infiniteCarousel to false.

Creating a looping list using RecyclerView is simple. Just override getItemCount() method in the RecyclerView Adapter. Example code:

override fun getItemCount(): Int {
return if (dataList.isEmpty()) 0 else Integer.MAX_VALUE
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val item = dataList[position % dataList.size]

// …
}

Then at the start just scroll to the middle point of the list to make it feel like it’s infinite.

recyclerView.scrollToPosition(Integer.MAX_VALUE / 2)

But the challenge is, for CarouselType.SHOWCASE, the current position item view is not get centered automatically! We could use scrollToPosition() method with smoothScrollToPosition() to make it center. But it is not smooth and creates bugs. When the first time the view is loaded you will see some glitch 😐. So to solve this, we used the scrollToPositionWithOffset() method and manually calculated the offset.

val view = layoutManager.findViewByPosition(0)layoutManager.scrollToPositionWithOffset(
finalPosition,
recyclerView.width / 2 - view.width / 2
)

See the source for details.

✨ Touch-to-pause support

If auto-play is turned on, then on touch down 👇 it will be paused and will be resumed on touch up ☝. I first tried it with recyclerView.setOnTouchListener() method, but it does not receive ACTION_DOWN event! Finally, I override the onInterceptTouchEvent() method to solve the problem. See the source for details.

There is a limitation though if the user touches down and swipes to left or right, the carousel will not resume. But you can resume it just by touching the carousel again. If you find any solution to this limitation then give me a PR. 🎈

🌿 “ImageCarousel” is now a lifecycle-aware component

Android introduced lifecycle-aware components to bind any component with the lifecycle of an Activity or Fragment or any Lifecycle-Owner. ImageCarouse is now a lifecycle-aware component. You should register lifecycle using the registerLifecycle() method. For Activity the parameter will be lifecycle/getLifecycle() and for Fragment it will be viewLifecycleOwner/getViewLifecycleOwner().

It is recommended if you enabled auto-play & infinite carousel. so that the auto-play/scroll will pause when the app is in the background. It is also used to correctly initialize the infinite carousel when the app is in the background.

💡 More use cases and inspiring samples

The samples are refreshed and added more use-cases and inspiring examples. Check out the samples here.

What next… 🤔

Try it… Clone it… Fork it… Check out the library source code… Give us suggestions, ideas, PRs…

Finally, share the library with your friends and colleagues 😁.

--

--