Rahul
Rahul

Reputation: 10625

Kotlin - How to add OnPageChangeListener in ViewPager

I am new in kotlin, How can I add OnPageChangeListener in a ViewPager.

viewPager?.addOnPageChangeListener // Now how can I add listener to it.

Upvotes: 48

Views: 31284

Answers (4)

Vishist Varugeese
Vishist Varugeese

Reputation: 1580

For ViewPager2 you can do it using OnPageChangeCallBack,

viewPager2?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
        override fun onPageSelected(position: Int) {
            super.onPageSelected(position)
        }

        override fun onPageScrollStateChanged(state: Int) {
            super.onPageScrollStateChanged(state)
        }

        override fun onPageScrolled(position: Int,
                                    positionOffset: Float,
                                    positionOffsetPixels: Int) {
            super.onPageScrolled(position, positionOffset, positionOffsetPixels)
        }
    })

Upvotes: 20

Vasily Kabunov
Vasily Kabunov

Reputation: 6761

Since most of the times we need to override only one of three ViewPager.OnPageChangeListener's methods (usually onPageSelected), this might be useful to reduce the code:

viewPager?.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {

    //override only methods you need, not all of them

    override fun onPageSelected(position: Int) {

    }
})

Upvotes: 6

themichaelscott
themichaelscott

Reputation: 496

If you'd like to leverage the power of Kotlin one step further, you could simplify usage of the ViewPager.OnPageChangeListener by creating your own custom listener for each of the three methods. Each listener handles one of the actions defined in the OnPageChangedListener: onPageScrolled(), onPageSelected() and onPageScrollStateChanged(). Usually you are only overriding one of the methods anyway and this way you can quickly add an implementation that does what you want to do without worrying about the other two methods. This is similar to what Butterknife was accomplishing with its annotations @OnPageSelected, etc.

To do this, create the class(es) you'd like to use:

// ViewPagerOnPageSelected.kt
class ViewPagerOnPageSelected(private val pageSelected: (Int) -> Unit = {}) : ViewPager.OnPageChangeListener {

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

    override fun onPageSelected(position: Int) {
        pageSelected(position)
    }

    override fun onPageScrollStateChanged(state: Int) {}
}

// ViewPagerOnPageScrolled.kt
class ViewPagerOnPageScrolled(private val pageScrolled: (Int, Float, Int) -> Unit = { _, _, _ -> }) : ViewPager.OnPageChangeListener {

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        pageScrolled(position, positionOffset, positionOffsetPixels)
    }

    override fun onPageSelected(position: Int) {}

    override fun onPageScrollStateChanged(state: Int) {}
}

// ViewPagerScrollStateChanged.kt
class ViewPagerScrollStateChanged(private val pageScrollStateChanged: (Int) -> Unit = {}) : ViewPager.OnPageChangeListener {

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}

    override fun onPageSelected(position: Int) {}

    override fun onPageScrollStateChanged(state: Int) {
        pageScrollStateChanged(state)
    }
}

Now that you have your classes (or be honest, the one most used is onPageSelected(), so you could just create that one) you can implement them in your Activity.

// MyActivity.kt 
viewPager.addOnPageChangeListener(ViewPagerOnPageSelected(this@MyActivity::onPageSelected))

private fun onPageSelected(position: Int) {
    // add your code here
}

You can even add a second or third listener

// MyActivity.kt 
viewPager.addOnPageChangeListener(ViewPagerOnPageSelected(this@MyActivity::onPageSelected))
viewPager.addOnPageChangeListener(ViewPagerScrollStateChanged(this@MyActivity::onPageScrollStateChanged))

private fun onPageSelected(position: Int) {
    // add your code here
}

private fun onPageScrollStateChanged(state: Int) {
    // add your code here
}

Kotlin is great for this but it applies not only to the ViewPager listener but for any Android interface that requires multiple methods to be overridden even though you only care to override one.

Note: Don't forget that the listener's onPageSelected() doesn't get called on the initial startup so if you'd like to take action on the first page you'll need to do it outside of this listener method.

Good luck!!!

Upvotes: 4

Rahul
Rahul

Reputation: 10625

I found it is quite simple, but it took my time as I am new in kotlin. I hope it will save others time one day.

viewPager?.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {

            override fun onPageScrollStateChanged(state: Int) {
            }

            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {

            }
            override fun onPageSelected(position: Int) {

            }

        })

or we can implement ViewPager.OnPageChangeListener in our Activity or Fragment then just use viewPager?.addOnPageChangeListener(this) but make sure to implement overrided methods.

Upvotes: 109

Related Questions