Skip to content

Commit

Permalink
[#40] ViewPager2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
tommybuonomo committed Aug 31, 2019
1 parent 80b3322 commit 7d53cac
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 53 deletions.
2 changes: 1 addition & 1 deletion viewpagerdotsindicator/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta03'
}

dokka {
Expand All @@ -50,7 +51,6 @@ buildscript {
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:${dokka_version}"

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import android.util.TypedValue
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver
import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback

abstract class BaseDotsIndicator @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null,
Expand Down Expand Up @@ -53,8 +56,6 @@ abstract class BaseDotsIndicator @JvmOverloads constructor(context: Context,
@JvmField
protected val dots = ArrayList<ImageView>()

private var onPageChangeListener: OnPageChangeListener? = null

var dotsClickable: Boolean = true
var dotsColor: Int = DEFAULT_POINT_COLOR
set(value) {
Expand All @@ -79,34 +80,28 @@ abstract class BaseDotsIndicator @JvmOverloads constructor(context: Context,
}
}

var viewPager: ViewPager? = null
set(value) {
if (value!!.adapter == null) {
throw IllegalStateException("You have to set an adapter to the view pager before " +
"initializing the dots indicator !")
}
field = value

value.adapter!!.registerDataSetObserver(object : DataSetObserver() {
override fun onChanged() {
super.onChanged()
refreshDots()
}
})
var pager: Pager? = null

refreshDots()
}
interface Pager {
val isNotEmpty: Boolean
val currentItem: Int
val isEmpty: Boolean
val count: Int
fun setCurrentItem(item: Int, smoothScroll: Boolean)
fun removeOnPageChangeListener()
fun addOnPageChangeListener(onPageChangeListenerHelper: OnPageChangeListenerHelper)
}

override fun onAttachedToWindow() {
super.onAttachedToWindow()
refreshDots()
}

private fun refreshDotsCount() {
if (dots.size < viewPager!!.adapter!!.count) {
addDots(viewPager!!.adapter!!.count - dots.size)
} else if (dots.size > viewPager!!.adapter!!.count) {
removeDots(dots.size - viewPager!!.adapter!!.count)
if (dots.size < pager!!.count) {
addDots(pager!!.count - dots.size)
} else if (dots.size > pager!!.count) {
removeDots(dots.size - pager!!.count)
}
}

Expand Down Expand Up @@ -147,16 +142,16 @@ abstract class BaseDotsIndicator @JvmOverloads constructor(context: Context,
}

private fun refreshOnPageChangedListener() {
if (viewPager!!.isNotEmpty) {
onPageChangeListener?.let { viewPager!!.removeOnPageChangeListener(it) }
onPageChangeListener = buildOnPageChangedListener()
viewPager!!.addOnPageChangeListener(onPageChangeListener!!)
onPageChangeListener!!.onPageScrolled(viewPager!!.currentItem, 0f, 0)
if (pager!!.isNotEmpty) {
pager!!.removeOnPageChangeListener()
val onPageChangeListenerHelper = buildOnPageChangedListener()
pager!!.addOnPageChangeListener(onPageChangeListenerHelper)
onPageChangeListenerHelper.onPageScrolled(pager!!.currentItem, 0f)
}
}

private fun refreshDotsSize() {
for (i in 0 until viewPager!!.currentItem) {
for (i in 0 until pager!!.currentItem) {
dots[i].setWidth(dotsSize.toInt())
}
}
Expand All @@ -166,7 +161,7 @@ abstract class BaseDotsIndicator @JvmOverloads constructor(context: Context,
abstract fun refreshDotColor(index: Int)
abstract fun addDot(index: Int)
abstract fun removeDot(index: Int)
abstract fun buildOnPageChangedListener(): OnPageChangeListener
abstract fun buildOnPageChangedListener(): OnPageChangeListenerHelper
abstract val type: Type

// PUBLIC METHODS
Expand All @@ -177,6 +172,110 @@ abstract class BaseDotsIndicator @JvmOverloads constructor(context: Context,
refreshDotsColors()
}

fun setViewPager(viewPager: ViewPager) {
if (viewPager.adapter == null) {
throw IllegalStateException("You have to set an adapter to the view pager before " +
"initializing the dots indicator !")
}

viewPager.adapter!!.registerDataSetObserver(object : DataSetObserver() {
override fun onChanged() {
super.onChanged()
refreshDots()
}
})

pager = object : Pager {
var onPageChangeListener: OnPageChangeListener? = null

override val isNotEmpty: Boolean
get() = viewPager.isNotEmpty
override val currentItem: Int
get() = viewPager.currentItem
override val isEmpty: Boolean
get() = viewPager.isEmpty
override val count: Int
get() = viewPager.adapter?.count ?: 0

override fun setCurrentItem(item: Int, smoothScroll: Boolean) {
viewPager.setCurrentItem(item, smoothScroll)
}

override fun removeOnPageChangeListener() {
onPageChangeListener?.let { viewPager.removeOnPageChangeListener(it) }
}

override fun addOnPageChangeListener(onPageChangeListenerHelper:
OnPageChangeListenerHelper) {
onPageChangeListener = object : OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float,
positionOffsetPixels: Int) {
onPageChangeListenerHelper.onPageScrolled(position, positionOffset)
}

override fun onPageScrollStateChanged(state: Int) {
}

override fun onPageSelected(position: Int) {
}
}
viewPager.addOnPageChangeListener(onPageChangeListener!!)
}
}

refreshDots()
}

fun setViewPager2(viewPager2: ViewPager2) {
if (viewPager2.adapter == null) {
throw IllegalStateException("You have to set an adapter to the view pager before " +
"initializing the dots indicator !")
}


viewPager2.adapter!!.registerAdapterDataObserver(object : AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
refreshDots()
}
})

pager = object : Pager {
var onPageChangeCallback: OnPageChangeCallback? = null

override val isNotEmpty: Boolean
get() = viewPager2.isNotEmpty
override val currentItem: Int
get() = viewPager2.currentItem
override val isEmpty: Boolean
get() = viewPager2.isEmpty
override val count: Int
get() = viewPager2.adapter?.itemCount ?: 0

override fun setCurrentItem(item: Int, smoothScroll: Boolean) {
viewPager2.setCurrentItem(item, smoothScroll)
}

override fun removeOnPageChangeListener() {
onPageChangeCallback?.let { viewPager2.unregisterOnPageChangeCallback(it) }
}

override fun addOnPageChangeListener(
onPageChangeListenerHelper: OnPageChangeListenerHelper) {
onPageChangeCallback = object : OnPageChangeCallback() {
override fun onPageScrolled(position: Int, positionOffset: Float,
positionOffsetPixels: Int) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels)
onPageChangeListenerHelper.onPageScrolled(position, positionOffset)
}
}
viewPager2.registerOnPageChangeCallback(onPageChangeCallback!!)
}
}

refreshDots()
}

// EXTENSIONS

fun View.setWidth(width: Int) {
Expand All @@ -195,7 +294,13 @@ abstract class BaseDotsIndicator @JvmOverloads constructor(context: Context,
}

protected val ViewPager.isNotEmpty: Boolean get() = adapter!!.count > 0
protected val ViewPager2.isNotEmpty: Boolean get() = adapter!!.itemCount > 0

protected val ViewPager?.isEmpty: Boolean
get() = this != null && this.adapter != null &&
adapter!!.count == 0

protected val ViewPager2?.isEmpty: Boolean
get() = this != null && this.adapter != null &&
adapter!!.itemCount == 0
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,13 @@ class DotsIndicator @JvmOverloads constructor(context: Context, attrs: Attribute
if (isInEditMode) {
background.setColor(if (0 == index) selectedDotColor else dotsColor)
} else {
background.setColor(if (viewPager!!.currentItem == index) selectedDotColor else dotsColor)
background.setColor(if (pager!!.currentItem == index) selectedDotColor else dotsColor)
}
imageView.setBackgroundDrawable(background)

dot.setOnClickListener {
if (dotsClickable && viewPager != null && viewPager!!.adapter != null && index < viewPager!!.adapter!!
.count) {
viewPager!!.setCurrentItem(index, true)
if (dotsClickable && index < pager?.count ?: 0) {
pager!!.setCurrentItem(index, true)
}
}

Expand Down Expand Up @@ -119,7 +118,7 @@ class DotsIndicator @JvmOverloads constructor(context: Context, attrs: Attribute

nextDotBackground.setColor(nextColor)

if (progressMode && selectedPosition <= viewPager!!.currentItem) {
if (progressMode && selectedPosition <= pager!!.currentItem) {
selectedDotBackground.setColor(selectedDotColor)
} else {
selectedDotBackground.setColor(selectedColor)
Expand All @@ -144,7 +143,7 @@ class DotsIndicator @JvmOverloads constructor(context: Context, attrs: Attribute
val elevationItem = dots[index]
val background = elevationItem.background as DotsGradientDrawable

if (index == viewPager!!.currentItem || progressMode && index < viewPager!!.currentItem) {
if (index == pager!!.currentItem || progressMode && index < pager!!.currentItem) {
background.setColor(selectedDotColor)
} else {
background.setColor(dotsColor)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.tbuonomo.viewpagerdotsindicator

import androidx.viewpager.widget.ViewPager

abstract class OnPageChangeListenerHelper : ViewPager.OnPageChangeListener {
abstract class OnPageChangeListenerHelper {
private var lastLeftPosition: Int = -1
private var lastRightPosition: Int = -1

internal abstract val pageCount: Int

override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
fun onPageScrolled(position: Int, positionOffset: Float) {
var offset = (position + positionOffset)
val lastPageIndex = (pageCount - 1).toFloat()
if (offset == lastPageIndex) {
Expand All @@ -20,24 +18,23 @@ abstract class OnPageChangeListenerHelper : ViewPager.OnPageChangeListener {

if (lastLeftPosition != -1) {
if (leftPosition > lastLeftPosition) {
resetPosition(lastLeftPosition)
(lastLeftPosition until leftPosition).forEach {
resetPosition(it)
}
}

if (rightPosition < lastRightPosition) {
resetPosition(lastRightPosition)
((rightPosition + 1)..lastRightPosition).forEach {
resetPosition(it)
}
}
}

lastLeftPosition = leftPosition
lastRightPosition = rightPosition
}

override fun onPageSelected(position: Int) {
// Empty
}

override fun onPageScrollStateChanged(i: Int) {}

internal abstract fun onPageScrolled(selectedPosition: Int, nextPosition: Int,
positionOffset: Float)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class SpringDotsIndicator @JvmOverloads constructor(context: Context, attrs: Att
}

private fun setUpDotIndicator() {
if (viewPager.isEmpty) {
if (pager?.isEmpty == true) {
return
}

Expand All @@ -100,8 +100,8 @@ class SpringDotsIndicator @JvmOverloads constructor(context: Context, attrs: Att
override fun addDot(index: Int) {
val dot = buildDot(true)
dot.setOnClickListener {
if (dotsClickable && viewPager != null && viewPager!!.adapter != null && index < viewPager!!.adapter!!.count) {
viewPager!!.setCurrentItem(index, true)
if (dotsClickable && index < pager?.count ?: 0) {
pager!!.setCurrentItem(index, true)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class WormDotsIndicator @JvmOverloads constructor(context: Context, attrs: Attri
}

private fun setUpDotIndicator() {
if (viewPager.isEmpty) {
if (pager?.isEmpty == true) {
return
}

Expand Down Expand Up @@ -104,8 +104,8 @@ class WormDotsIndicator @JvmOverloads constructor(context: Context, attrs: Attri
override fun addDot(index: Int) {
val dot = buildDot(true)
dot.setOnClickListener {
if (dotsClickable && viewPager != null && viewPager!!.adapter != null && index < viewPager!!.adapter!!.count) {
viewPager!!.setCurrentItem(index, true)
if (dotsClickable && index < pager?.count ?: 0) {
pager!!.setCurrentItem(index, true)
}
}

Expand Down

0 comments on commit 7d53cac

Please sign in to comment.