| @ -1,33 +0,0 @@ | |||||
| package com.nivesh.production.niveshfd.fd.util.attacher | |||||
| import com.nivesh.production.niveshfd.fd.util.dotIndicator.BaseDotsIndicator | |||||
| internal abstract class DotsIndicatorAttacher<Attachable, Adapter> { | |||||
| fun setup(baseDotsIndicator: BaseDotsIndicator, attachable: Attachable) { | |||||
| val adapter = getAdapterFromAttachable(attachable) | |||||
| ?: throw IllegalStateException( | |||||
| "Please set an adapter to the view pager (1 or 2) or the recycler before initializing the dots indicator" | |||||
| ) | |||||
| registerAdapterDataChangedObserver(attachable, adapter) { | |||||
| baseDotsIndicator.post { baseDotsIndicator.refreshDots() } | |||||
| } | |||||
| baseDotsIndicator.pager = buildPager(attachable, adapter) | |||||
| baseDotsIndicator.refreshDots() | |||||
| } | |||||
| abstract fun getAdapterFromAttachable(attachable: Attachable): Adapter? | |||||
| abstract fun registerAdapterDataChangedObserver( | |||||
| attachable: Attachable, | |||||
| adapter: Adapter, | |||||
| onChanged: () -> Unit | |||||
| ) | |||||
| abstract fun buildPager( | |||||
| attachable: Attachable, | |||||
| adapter: Adapter, | |||||
| ): BaseDotsIndicator.Pager | |||||
| } | |||||
| @ -1,66 +0,0 @@ | |||||
| package com.nivesh.production.niveshfd.fd.util.attacher | |||||
| import android.database.DataSetObserver | |||||
| import androidx.viewpager.widget.PagerAdapter | |||||
| import androidx.viewpager.widget.ViewPager | |||||
| import com.nivesh.production.niveshfd.fd.util.dotIndicator.BaseDotsIndicator | |||||
| import com.nivesh.production.niveshfd.fd.util.dotIndicator.OnPageChangeListenerHelper | |||||
| import com.nivesh.production.niveshfd.fd.util.dotIndicator.isEmpty | |||||
| internal class ViewPagerAttacher : | |||||
| DotsIndicatorAttacher<ViewPager, PagerAdapter>() { | |||||
| override fun getAdapterFromAttachable(attachable: ViewPager): PagerAdapter? = attachable.adapter | |||||
| override fun registerAdapterDataChangedObserver( | |||||
| attachable: ViewPager, | |||||
| adapter: PagerAdapter, | |||||
| onChanged: () -> Unit | |||||
| ) { | |||||
| adapter.registerDataSetObserver(object : DataSetObserver() { | |||||
| override fun onChanged() { | |||||
| super.onChanged() | |||||
| onChanged() | |||||
| } | |||||
| }) | |||||
| } | |||||
| override fun buildPager(attachable: ViewPager, adapter: PagerAdapter): BaseDotsIndicator.Pager { | |||||
| return object : BaseDotsIndicator.Pager { | |||||
| var onPageChangeListener: ViewPager.OnPageChangeListener? = null | |||||
| override val isNotEmpty: Boolean get() = attachable.isEmpty | |||||
| override val currentItem: Int get() = attachable.currentItem | |||||
| override val isEmpty: Boolean get() = attachable.isEmpty | |||||
| override val count: Int get() = attachable.adapter?.count ?: 0 | |||||
| override fun setCurrentItem(item: Int, smoothScroll: Boolean) { | |||||
| attachable.setCurrentItem(item, smoothScroll) | |||||
| } | |||||
| override fun removeOnPageChangeListener() { | |||||
| onPageChangeListener?.let { attachable.removeOnPageChangeListener(it) } | |||||
| } | |||||
| override fun addOnPageChangeListener( | |||||
| onPageChangeListenerHelper: | |||||
| OnPageChangeListenerHelper | |||||
| ) { | |||||
| onPageChangeListener = object : ViewPager.OnPageChangeListener { | |||||
| override fun onPageScrolled( | |||||
| position: Int, positionOffset: Float, | |||||
| positionOffsetPixels: Int | |||||
| ) { | |||||
| onPageChangeListenerHelper.onPageScrolled(position, positionOffset) | |||||
| } | |||||
| override fun onPageScrollStateChanged(state: Int) { | |||||
| } | |||||
| override fun onPageSelected(position: Int) { | |||||
| } | |||||
| } | |||||
| attachable.addOnPageChangeListener(onPageChangeListener!!) | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -1,227 +0,0 @@ | |||||
| package com.nivesh.production.niveshfd.fd.util.dotIndicator | |||||
| import android.content.Context | |||||
| import android.graphics.Color | |||||
| import android.os.Build | |||||
| import android.os.Parcelable | |||||
| import android.util.AttributeSet | |||||
| import android.view.View | |||||
| import android.widget.FrameLayout | |||||
| import android.widget.ImageView | |||||
| import androidx.annotation.StyleableRes | |||||
| import androidx.viewpager.widget.ViewPager | |||||
| import androidx.viewpager2.widget.ViewPager2 | |||||
| import com.nivesh.production.niveshfd.R | |||||
| import com.nivesh.production.niveshfd.fd.util.attacher.ViewPagerAttacher | |||||
| abstract class BaseDotsIndicator @JvmOverloads constructor( | |||||
| context: Context, | |||||
| attrs: AttributeSet? = null, | |||||
| defStyleAttr: Int = 0 | |||||
| ) : FrameLayout(context, attrs, defStyleAttr) { | |||||
| companion object { | |||||
| const val DEFAULT_POINT_COLOR = Color.CYAN | |||||
| } | |||||
| enum class Type( | |||||
| val defaultSize: Float, | |||||
| val defaultSpacing: Float, | |||||
| @StyleableRes val styleableId: IntArray, | |||||
| @StyleableRes val dotsColorId: Int, | |||||
| @StyleableRes val dotsSizeId: Int, | |||||
| @StyleableRes val dotsSpacingId: Int, | |||||
| @StyleableRes val dotsCornerRadiusId: Int, | |||||
| @StyleableRes val dotsClickableId: Int | |||||
| ) { | |||||
| DEFAULT( | |||||
| 16f, | |||||
| 8f, | |||||
| R.styleable.SpringDotsIndicator, | |||||
| R.styleable.SpringDotsIndicator_dotsColor, | |||||
| R.styleable.SpringDotsIndicator_dotsSize, | |||||
| R.styleable.SpringDotsIndicator_dotsSpacing, | |||||
| R.styleable.SpringDotsIndicator_dotsCornerRadius, | |||||
| R.styleable.SpringDotsIndicator_dotsClickable | |||||
| ), | |||||
| SPRING( | |||||
| 16f, | |||||
| 4f, | |||||
| R.styleable.DotsIndicator, | |||||
| R.styleable.DotsIndicator_dotsColor, | |||||
| R.styleable.DotsIndicator_dotsSize, | |||||
| R.styleable.DotsIndicator_dotsSpacing, | |||||
| R.styleable.DotsIndicator_dotsCornerRadius, | |||||
| R.styleable.SpringDotsIndicator_dotsClickable | |||||
| ), | |||||
| WORM( | |||||
| 16f, | |||||
| 4f, | |||||
| R.styleable.WormDotsIndicator, | |||||
| R.styleable.WormDotsIndicator_dotsColor, | |||||
| R.styleable.WormDotsIndicator_dotsSize, | |||||
| R.styleable.WormDotsIndicator_dotsSpacing, | |||||
| R.styleable.WormDotsIndicator_dotsCornerRadius, | |||||
| R.styleable.SpringDotsIndicator_dotsClickable | |||||
| ) | |||||
| } | |||||
| @JvmField | |||||
| protected val dots = ArrayList<ImageView>() | |||||
| var dotsClickable: Boolean = true | |||||
| var dotsColor: Int = DEFAULT_POINT_COLOR | |||||
| set(value) { | |||||
| field = value | |||||
| refreshDotsColors() | |||||
| } | |||||
| protected var dotsSize = dpToPxF(type.defaultSize) | |||||
| protected var dotsCornerRadius = dotsSize / 2f | |||||
| protected var dotsSpacing = dpToPxF(type.defaultSpacing) | |||||
| init { | |||||
| if (attrs != null) { | |||||
| val a = context.obtainStyledAttributes(attrs, type.styleableId) | |||||
| dotsColor = a.getColor(type.dotsColorId, DEFAULT_POINT_COLOR) | |||||
| dotsSize = a.getDimension(type.dotsSizeId, dotsSize) | |||||
| dotsCornerRadius = a.getDimension(type.dotsCornerRadiusId, dotsCornerRadius) | |||||
| dotsSpacing = a.getDimension(type.dotsSpacingId, dotsSpacing) | |||||
| dotsClickable = a.getBoolean(type.dotsClickableId, true) | |||||
| a.recycle() | |||||
| } | |||||
| } | |||||
| var pager: Pager? = null | |||||
| 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() | |||||
| post { refreshDots() } | |||||
| } | |||||
| private fun refreshDotsCount() { | |||||
| if (dots.size < pager!!.count) { | |||||
| addDots(pager!!.count - dots.size) | |||||
| } else if (dots.size > pager!!.count) { | |||||
| removeDots(dots.size - pager!!.count) | |||||
| } | |||||
| } | |||||
| protected fun refreshDotsColors() { | |||||
| for (i in dots.indices) { | |||||
| refreshDotColor(i) | |||||
| } | |||||
| } | |||||
| protected fun dpToPx(dp: Int): Int { | |||||
| return (context.resources.displayMetrics.density * dp).toInt() | |||||
| } | |||||
| protected fun dpToPxF(dp: Float): Float { | |||||
| return context.resources.displayMetrics.density * dp | |||||
| } | |||||
| protected fun addDots(count: Int) { | |||||
| for (i in 0 until count) { | |||||
| addDot(i) | |||||
| } | |||||
| } | |||||
| private fun removeDots(count: Int) { | |||||
| for (i in 0 until count) { | |||||
| removeDot() | |||||
| } | |||||
| } | |||||
| fun refreshDots() { | |||||
| if (pager == null) { | |||||
| return | |||||
| } | |||||
| post { | |||||
| // Check if we need to refresh the dots count | |||||
| refreshDotsCount() | |||||
| refreshDotsColors() | |||||
| refreshDotsSize() | |||||
| refreshOnPageChangedListener() | |||||
| } | |||||
| } | |||||
| private fun refreshOnPageChangedListener() { | |||||
| if (pager!!.isNotEmpty) { | |||||
| pager!!.removeOnPageChangeListener() | |||||
| val onPageChangeListenerHelper = buildOnPageChangedListener() | |||||
| pager!!.addOnPageChangeListener(onPageChangeListenerHelper) | |||||
| onPageChangeListenerHelper.onPageScrolled(pager!!.currentItem, 0f) | |||||
| } | |||||
| } | |||||
| private fun refreshDotsSize() { | |||||
| dots.forEach { it.setWidth(dotsSize.toInt()) } | |||||
| } | |||||
| // ABSTRACT METHODS AND FIELDS | |||||
| abstract fun refreshDotColor(index: Int) | |||||
| abstract fun addDot(index: Int) | |||||
| abstract fun removeDot() | |||||
| abstract fun buildOnPageChangedListener(): OnPageChangeListenerHelper | |||||
| abstract val type: Type | |||||
| // PUBLIC METHODS | |||||
| @Deprecated( | |||||
| "Use setDotsColors(color) instead", ReplaceWith("setDotsColors(color)") | |||||
| ) | |||||
| fun setPointsColor(color: Int) { | |||||
| dotsColor = color | |||||
| refreshDotsColors() | |||||
| } | |||||
| @Deprecated( | |||||
| "Use attachTo(viewPager) instead", ReplaceWith("attachTo(viewPager)") | |||||
| ) | |||||
| fun setViewPager(viewPager: ViewPager) { | |||||
| ViewPagerAttacher().setup(this, viewPager) | |||||
| } | |||||
| @Deprecated( | |||||
| "Use attachTo(viewPager) instead", ReplaceWith("attachTo(viewPager)") | |||||
| ) | |||||
| // fun setViewPager2(viewPager2: ViewPager2) { | |||||
| // ViewPager2Attacher().setup(this, viewPager2) | |||||
| // } | |||||
| fun attachTo(viewPager: ViewPager) { | |||||
| ViewPagerAttacher().setup(this, viewPager) | |||||
| } | |||||
| // fun attachTo(viewPager2: ViewPager2) { | |||||
| // ViewPager2Attacher().setup(this, viewPager2) | |||||
| // } | |||||
| override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { | |||||
| super.onLayout(changed, left, top, right, bottom) | |||||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && layoutDirection == View.LAYOUT_DIRECTION_RTL) { | |||||
| layoutDirection = View.LAYOUT_DIRECTION_LTR | |||||
| rotation = 180f | |||||
| requestLayout() | |||||
| } | |||||
| } | |||||
| override fun onRestoreInstanceState(state: Parcelable?) { | |||||
| super.onRestoreInstanceState(state) | |||||
| post { refreshDots() } | |||||
| } | |||||
| } | |||||
| @ -1,13 +0,0 @@ | |||||
| package com.nivesh.production.niveshfd.fd.util.dotIndicator | |||||
| import android.graphics.drawable.GradientDrawable | |||||
| class DotsGradientDrawable : GradientDrawable() { | |||||
| var currentColor: Int = 0 | |||||
| private set | |||||
| override fun setColor(argb: Int) { | |||||
| super.setColor(argb) | |||||
| currentColor = argb | |||||
| } | |||||
| } | |||||
| @ -1,205 +0,0 @@ | |||||
| package com.nivesh.production.niveshfd.fd.util.dotIndicator | |||||
| import android.animation.ArgbEvaluator | |||||
| import android.content.Context | |||||
| import android.os.Build | |||||
| import android.util.AttributeSet | |||||
| import android.util.Log | |||||
| import android.view.LayoutInflater | |||||
| import android.view.View | |||||
| import android.view.ViewGroup | |||||
| import android.widget.ImageView | |||||
| import android.widget.LinearLayout | |||||
| import com.nivesh.production.niveshfd.R | |||||
| class DotsIndicator @JvmOverloads constructor( | |||||
| context: Context, attrs: AttributeSet? = null, | |||||
| defStyleAttr: Int = 0 | |||||
| ) : BaseDotsIndicator(context, attrs, defStyleAttr) { | |||||
| companion object { | |||||
| const val DEFAULT_WIDTH_FACTOR = 2.5f | |||||
| } | |||||
| private lateinit var linearLayout: LinearLayout | |||||
| private var dotsWidthFactor: Float = 0f | |||||
| private var progressMode: Boolean = false | |||||
| private var dotsElevation: Float = 0f | |||||
| var selectedDotColor: Int = 0 | |||||
| set(value) { | |||||
| field = value | |||||
| refreshDotsColors() | |||||
| } | |||||
| private val argbEvaluator = ArgbEvaluator() | |||||
| init { | |||||
| init(attrs) | |||||
| } | |||||
| private fun init(attrs: AttributeSet?) { | |||||
| linearLayout = LinearLayout(context) | |||||
| linearLayout.orientation = LinearLayout.HORIZONTAL | |||||
| addView(linearLayout, | |||||
| ViewGroup.LayoutParams.WRAP_CONTENT, | |||||
| ViewGroup.LayoutParams.WRAP_CONTENT | |||||
| ) | |||||
| dotsWidthFactor = DEFAULT_WIDTH_FACTOR | |||||
| if (attrs != null) { | |||||
| val a = context.obtainStyledAttributes(attrs, R.styleable.DotsIndicator) | |||||
| selectedDotColor = | |||||
| a.getColor(R.styleable.DotsIndicator_selectedDotColor, DEFAULT_POINT_COLOR) | |||||
| dotsWidthFactor = a.getFloat(R.styleable.DotsIndicator_dotsWidthFactor, 2.5f) | |||||
| if (dotsWidthFactor < 1) { | |||||
| Log.w( | |||||
| "DotsIndicator", | |||||
| "The dotsWidthFactor can't be set under 1.0f, please set an higher value" | |||||
| ) | |||||
| dotsWidthFactor = 1f | |||||
| } | |||||
| progressMode = a.getBoolean(R.styleable.DotsIndicator_progressMode, false) | |||||
| dotsElevation = a.getDimension(R.styleable.DotsIndicator_dotsElevation, 0f) | |||||
| a.recycle() | |||||
| } | |||||
| if (isInEditMode) { | |||||
| addDots(5) | |||||
| refreshDots() | |||||
| } | |||||
| } | |||||
| override fun addDot(index: Int) { | |||||
| val dot = LayoutInflater.from(context).inflate(R.layout.dot_layout, this, false) | |||||
| val imageView = dot.findViewById<ImageView>(R.id.dot) | |||||
| val params = imageView.layoutParams as LayoutParams | |||||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | |||||
| dot.layoutDirection = View.LAYOUT_DIRECTION_LTR | |||||
| } | |||||
| params.height = dotsSize.toInt() | |||||
| params.width = params.height | |||||
| params.setMargins(dotsSpacing.toInt(), 0, dotsSpacing.toInt(), 0) | |||||
| val background = DotsGradientDrawable() | |||||
| background.cornerRadius = dotsCornerRadius | |||||
| if (isInEditMode) { | |||||
| background.setColor(if (0 == index) selectedDotColor else dotsColor) | |||||
| } else { | |||||
| background.setColor(if (pager!!.currentItem == index) selectedDotColor else dotsColor) | |||||
| } | |||||
| imageView.setBackgroundCompat(background) | |||||
| dot.setOnClickListener { | |||||
| if (dotsClickable && index < pager?.count ?: 0) { | |||||
| pager!!.setCurrentItem(index, true) | |||||
| } | |||||
| } | |||||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |||||
| dot.setPaddingHorizontal((dotsElevation * 0.8f).toInt()) | |||||
| dot.setPaddingVertical((dotsElevation * 2).toInt()) | |||||
| imageView.elevation = dotsElevation | |||||
| } | |||||
| dots.add(imageView) | |||||
| linearLayout.addView(dot) | |||||
| } | |||||
| override fun removeDot() { | |||||
| linearLayout.removeViewAt(linearLayout.childCount - 1) | |||||
| dots.removeAt(dots.size - 1) | |||||
| } | |||||
| override fun buildOnPageChangedListener(): OnPageChangeListenerHelper { | |||||
| return object : OnPageChangeListenerHelper() { | |||||
| override fun onPageScrolled( | |||||
| selectedPosition: Int, | |||||
| nextPosition: Int, | |||||
| positionOffset: Float | |||||
| ) { | |||||
| val selectedDot = dots[selectedPosition] | |||||
| // Selected dot | |||||
| val selectedDotWidth = | |||||
| (dotsSize + dotsSize * (dotsWidthFactor - 1) * (1 - positionOffset)).toInt() | |||||
| selectedDot.setWidth(selectedDotWidth) | |||||
| if (dots.isInBounds(nextPosition)) { | |||||
| val nextDot = dots[nextPosition] | |||||
| val nextDotWidth = | |||||
| (dotsSize + dotsSize * (dotsWidthFactor - 1) * positionOffset).toInt() | |||||
| nextDot.setWidth(nextDotWidth) | |||||
| val selectedDotBackground = selectedDot.background as DotsGradientDrawable | |||||
| val nextDotBackground = nextDot.background as DotsGradientDrawable | |||||
| if (selectedDotColor != dotsColor) { | |||||
| val selectedColor = argbEvaluator.evaluate( | |||||
| positionOffset, selectedDotColor, | |||||
| dotsColor | |||||
| ) as Int | |||||
| val nextColor = argbEvaluator.evaluate( | |||||
| positionOffset, dotsColor, | |||||
| selectedDotColor | |||||
| ) as Int | |||||
| nextDotBackground.setColor(nextColor) | |||||
| if (progressMode && selectedPosition <= pager!!.currentItem) { | |||||
| selectedDotBackground.setColor(selectedDotColor) | |||||
| } else { | |||||
| selectedDotBackground.setColor(selectedColor) | |||||
| } | |||||
| } | |||||
| } | |||||
| invalidate() | |||||
| } | |||||
| override fun resetPosition(position: Int) { | |||||
| dots[position].setWidth(dotsSize.toInt()) | |||||
| refreshDotColor(position) | |||||
| } | |||||
| override val pageCount: Int | |||||
| get() = dots.size | |||||
| } | |||||
| } | |||||
| override fun refreshDotColor(index: Int) { | |||||
| val elevationItem = dots[index] | |||||
| val background = elevationItem.background as? DotsGradientDrawable? | |||||
| background?.let { | |||||
| if (index == pager!!.currentItem || progressMode && index < pager!!.currentItem) { | |||||
| background.setColor(selectedDotColor) | |||||
| } else { | |||||
| background.setColor(dotsColor) | |||||
| } | |||||
| } | |||||
| elevationItem.setBackgroundCompat(background) | |||||
| elevationItem.invalidate() | |||||
| } | |||||
| override val type get() = Type.DEFAULT | |||||
| //********************************************************* | |||||
| // Users Methods | |||||
| //********************************************************* | |||||
| @Deprecated("Use setSelectedDotColor() instead", ReplaceWith("setSelectedDotColor()")) | |||||
| fun setSelectedPointColor(color: Int) { | |||||
| selectedDotColor = color | |||||
| } | |||||
| } | |||||
| @ -1,46 +0,0 @@ | |||||
| package com.nivesh.production.niveshfd.fd.util.dotIndicator | |||||
| import android.content.Context | |||||
| import android.graphics.drawable.Drawable | |||||
| import android.os.Build | |||||
| import android.util.TypedValue | |||||
| import android.view.View | |||||
| import androidx.viewpager.widget.ViewPager | |||||
| import androidx.viewpager2.widget.ViewPager2 | |||||
| import com.nivesh.production.niveshfd.R | |||||
| internal fun View.setPaddingHorizontal(padding: Int) { | |||||
| setPadding(padding, paddingTop, padding, paddingBottom) | |||||
| } | |||||
| internal fun View.setPaddingVertical(padding: Int) { | |||||
| setPadding(paddingLeft, padding, paddingRight, padding) | |||||
| } | |||||
| internal fun View.setWidth(width: Int) { | |||||
| layoutParams.apply { | |||||
| this.width = width | |||||
| requestLayout() | |||||
| } | |||||
| } | |||||
| internal fun <T> ArrayList<T>.isInBounds(index: Int) = index in 0 until size | |||||
| internal fun Context.getThemePrimaryColor(): Int { | |||||
| val value = TypedValue() | |||||
| this.theme.resolveAttribute(androidx.transition.R.attr.colorPrimary, value, true) | |||||
| return value.data | |||||
| } | |||||
| internal val ViewPager.isNotEmpty: Boolean get() = (adapter?.count ?: 0) > 0 | |||||
| internal val ViewPager2.isNotEmpty: Boolean get() = (adapter?.itemCount ?: 0) > 0 | |||||
| internal val ViewPager?.isEmpty: Boolean get() = this?.adapter?.count == 0 | |||||
| internal val ViewPager2?.isEmpty: Boolean get() = this?.adapter?.itemCount == 0 | |||||
| fun View.setBackgroundCompat(background: Drawable?) { | |||||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { | |||||
| this.background = background | |||||
| } else { | |||||
| setBackgroundDrawable(background) | |||||
| } | |||||
| } | |||||
| @ -1,49 +0,0 @@ | |||||
| package com.nivesh.production.niveshfd.fd.util.dotIndicator | |||||
| abstract class OnPageChangeListenerHelper { | |||||
| private var lastLeftPosition: Int = -1 | |||||
| private var lastRightPosition: Int = -1 | |||||
| internal abstract val pageCount: Int | |||||
| fun onPageScrolled(position: Int, positionOffset: Float) { | |||||
| var offset = (position + positionOffset) | |||||
| val lastPageIndex = (pageCount - 1).toFloat() | |||||
| if (offset == lastPageIndex) { | |||||
| offset = lastPageIndex - .0001f | |||||
| } | |||||
| val leftPosition = offset.toInt() | |||||
| val rightPosition = leftPosition + 1 | |||||
| if (rightPosition > lastPageIndex || leftPosition < 0) { | |||||
| return | |||||
| } | |||||
| onPageScrolled(leftPosition, rightPosition, offset % 1) | |||||
| if (lastLeftPosition != -1) { | |||||
| if (leftPosition > lastLeftPosition) { | |||||
| (lastLeftPosition until leftPosition).forEach { | |||||
| resetPosition(it) | |||||
| } | |||||
| } | |||||
| if (rightPosition < lastRightPosition) { | |||||
| resetPosition(lastRightPosition) | |||||
| ((rightPosition + 1)..lastRightPosition).forEach { | |||||
| resetPosition(it) | |||||
| } | |||||
| } | |||||
| } | |||||
| lastLeftPosition = leftPosition | |||||
| lastRightPosition = rightPosition | |||||
| } | |||||
| internal abstract fun onPageScrolled( | |||||
| selectedPosition: Int, nextPosition: Int, | |||||
| positionOffset: Float | |||||
| ) | |||||
| internal abstract fun resetPosition(position: Int) | |||||
| } | |||||
Powered by TurnKey Linux.