this is my code, This code will have an ellipsis that will scroll along the banner. and my banner can scroll automatically. You can try to apply it. Hope my code can help you.
//this is xml file
<com.yourdomain.epoxy.carousel.PagerSnapCarousel
android:id="@+id/carouselBanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<com.rd.PageIndicatorView
android:id="@+id/dots_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/carouselBanner"
app:piv_animationType="scale"
app:piv_dynamicCount="true"
app:piv_interactiveAnimation="true"
app:piv_radius="@dimen/_5sdp"
app:piv_orientation="horizontal" />
//And my epoxy model
data class MainPageGroupBannerModel(
var banner: MainPageBanner,
val callback: (NewsItem) -> Unit,
val callbackBanner: () -> Unit,
) : ViewBindingKotlinModel<ListItemMainPageBannerNewsBinding>(R.layout.list_item_main_page_banner_news) {
private var selectedPos: Int = 0
companion object {
private const val AUTO_SLIDE_INTERVAL = 5000L
}
lateinit var carouselBannerItem: RecyclerView
lateinit var cyclicAdapterItem: CyclicAdapter
val handler = Handler(Looper.getMainLooper())
override fun ListItemMainPageBannerNewsBinding.bind() {
carouselBannerItem = carouselBanner
val mainPageBannerController = MainPageBannerController(callbackBanner,callback)
val cyclicAdapter = CyclicAdapter(mainPageBannerController.adapter)
cyclicAdapterItem = cyclicAdapter
carouselBanner.apply {
swapAdapter(
when {
(banner.news?.size ?: return) > 1 -> cyclicAdapter
else -> mainPageBannerController.adapter
},
false
)
}
mainPageBannerController.setData(banner)
//ไข่ปลา
dotsIndicator.count = cyclicAdapter.actualItemCount
carouselBanner.clearOnScrollListeners()
carouselBanner.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val firstPosition =
(carouselBanner.layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition()
if (firstPosition != null && cyclicAdapter.actualItemCount != 0) {
selectedPos = firstPosition % cyclicAdapter.actualItemCount
dotsIndicator.selection = selectedPos
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
}
})
// Start auto-scrolling
handler.postDelayed(autoSlideRunnable, AUTO_SLIDE_INTERVAL)
}
private val autoSlideRunnable = object : Runnable {
override fun run() {
carouselBannerItem?.let { banner ->
val layoutManager = banner.layoutManager as LinearLayoutManager
val currentPosition = layoutManager.findFirstVisibleItemPosition()
val nextPosition = (currentPosition + 1) % cyclicAdapterItem.actualItemCount
banner.smoothScrollToPosition(nextPosition)
handler.postDelayed(this, AUTO_SLIDE_INTERVAL)
}
}
}
override fun unbind(view: View) {
handler.removeCallbacks(autoSlideRunnable)
super.unbind(view)
}
}