Implementing Auto Scroll in Recycler View

Duggu
GoMechanic
Published in
3 min readJun 3, 2020

Automatic horizontal scroll in recycler view idea came into the picture when we saw the news channels utilizing this feature in their time line running at the bottom of the screen. So we thought why don’t we use this in our app.

What will it look like?

So let’s talk about how to achieve the above idea. So the idea is to scroll the infinite recycler view element automatically.

Enough talking, show me the code

There you go.

Let’s start the implementation :-

What you need to do ?

You need to scroll the recycler view gradually using the post delay method of the handler.

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rvNews.apply {
val
dataArray : Array<String?> = resources.getStringArray(R.array.list_array)
adapter = NewsAdapter(dataArray,this@MainActivity)
layoutManager = llm
setHasFixedSize(true)
}
handler
.postDelayed(runnable, scroll.toLong())
}

private val llm: LinearLayoutManager = object : LinearLayoutManager(this , HORIZONTAL,false) {
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State, position: Int) {
val scroller: LinearSmoothScroller =
object : LinearSmoothScroller(this@MainActivity) {
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
return 2000f
}
}
scroller.targetPosition = position
startSmoothScroll(scroller)
}
}

Now you need to initialize your handler.

private val handler = Handler()
private val scroll = 0
private val runnable = object : Runnable {
var count = 0
override fun run() {
if (count == rvNews.adapter?.itemCount) count = 0
if (count < rvNews.adapter?.itemCount?:-1) {
rvNews.smoothScrollToPosition(++count)
handler.postDelayed(this, scroll.toLong())
}
}
}

Don’t forget to remove the listener in onStop() method and reinitialize at onResume() method.

override fun onResume() {
super.onResume()
handler.postDelayed(runnable, scroll.toLong())
}

override fun onStop() {
super.onStop()
handler.removeCallbacks(runnable)
}

That’s all for automatic scroll in recycler view.

Infinite scroll

What you need to do for infinite scroll ?

Simple answer is you need to make a recycler view list Integer.MAX.

Adapter code

override fun getItemCount(): Int = Integer.MAX_VALUE

Also getting data from a list on onBindViewHolder is like.

dataArray[layoutPosition%dataArray.size]?.let { model->
itemView
.tvNews.setOnClickListener(this)
itemView.tvNews.text = model
}

Click not working

Now while scrolling recycler view you wouldn’t be able to click on the list.

what to do ?

You just need to make your own recycler touch listener to handle the on recycler view and add into your recycler view.

addOnItemTouchListener(RecyclerTouchListener(this@MainActivity, object : RecyclerTouchListener.ClickListener {
@SuppressLint("Recycle")
override fun onClick(view: View?, position: Int) {
dataArray[position%dataArray.size]?.let { model ->
Toast.makeText(this@MainActivity,model,Toast.LENGTH_LONG).show()
}
}
}))

How touch listener class look like:-

You need to implement onItemTouchListener into your class. Now you need to override onInterceptTouchEvent and handle click on item.

All set , now you need to findChildView from touch event x-axis and y-axis. When you get child view from onInterceptTouchEvent . Just pass recycler child view to to your activity class for click handling.

class RecyclerTouchListener(context: Context?,private val clickListener: ClickListener?) : OnItemTouchListener {
private val gestureDetector: GestureDetector = GestureDetector(context, object : SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent): Boolean {
return true
}

override fun onLongPress(e: MotionEvent) {
}
})

override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
val child: View? = rv.findChildViewUnder(e.x, e.y)
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildLayoutPosition(child))
}
return false
}

override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
interface ClickListener {
fun onClick(view: View?, position: Int)
}

}

Adding Dependencies
Modify your build.gradle file for app module to add dependencies for

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'

implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

After clicking, This is how it looks like :-

All Good, Hit Run!

Now everything seems good, hit run and see your beautiful final result. So you can see how easy it is to add auto scroll in recycler views and also using Kotlin for development make development much more fun and easy.

Happy Coding!

Hope you liked the post

--

--