Avoid divide by zero

This commit is contained in:
Christophe Smet
2018-10-30 14:27:56 +01:00
parent da9fbb3106
commit 5740def0f9

View File

@ -2,17 +2,18 @@ package com.littlemango.stacklayoutmanager
import android.support.annotation.IntRange
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.RecyclerView.*
import android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING
import android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE
import android.view.View
import android.view.ViewGroup
class StackLayoutManager(scrollOrientation: ScrollOrientation,
visibleCount: Int,
animation: Class<out StackAnimation>,
layout: Class<out StackLayout>) : RecyclerView.LayoutManager() {
private enum class FlingOrientation{NONE, LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}
visibleCount: Int,
animation: Class<out StackAnimation>,
layout: Class<out StackLayout>) : RecyclerView.LayoutManager() {
private enum class FlingOrientation { NONE, LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP }
enum class ScrollOrientation{LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}
enum class ScrollOrientation { LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP }
private var mVisibleItemCount = visibleCount
@ -91,7 +92,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
* 设置recyclerView 静止时候可见的itemView 个数.
* @param count 可见 itemView默认为3
*/
fun setVisibleItemCount(@IntRange(from = 1, to = Long.MAX_VALUE)count: Int) {
fun setVisibleItemCount(@IntRange(from = 1, to = Long.MAX_VALUE) count: Int) {
mVisibleItemCount = Math.min(itemCount - 1, Math.max(1, count))
mAnimation?.setVisibleCount(mVisibleItemCount)
}
@ -153,7 +154,10 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
* @return 返回第一个可见 itemView 的位置.
*/
fun getFirstVisibleItemPosition(): Int {
return when(mScrollOrientation) {
if (width == 0 || height == 0) {
return 0
}
return when (mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT -> Math.floor((mScrollOffset * 1.0 / width)).toInt()
ScrollOrientation.LEFT_TO_RIGHT -> itemCount - 1 - Math.ceil((mScrollOffset * 1.0 / width)).toInt()
ScrollOrientation.BOTTOM_TO_TOP -> Math.floor((mScrollOffset * 1.0 / height)).toInt()
@ -175,7 +179,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
constructor() : this(ScrollOrientation.RIGHT_TO_LEFT)
init {
mScrollOffset = when(mScrollOrientation) {
mScrollOffset = when (mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.BOTTOM_TO_TOP -> 0
else -> Int.MAX_VALUE
}
@ -208,7 +212,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
mOnFlingListener = object : RecyclerView.OnFlingListener() {
override fun onFling(velocityX: Int, velocityY: Int): Boolean {
if (mPagerMode) {
when(mScrollOrientation) {
when (mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.LEFT_TO_RIGHT -> {
mFlingOrientation = when {
velocityX > mPagerFlingVelocity -> FlingOrientation.RIGHT_TO_LEFT
@ -264,27 +268,35 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
}
override fun canScrollHorizontally(): Boolean {
return when(mScrollOrientation) {
if (itemCount == 0) {
return false
}
return when (mScrollOrientation) {
ScrollOrientation.LEFT_TO_RIGHT, ScrollOrientation.RIGHT_TO_LEFT -> true
else -> false
}
}
override fun canScrollVertically(): Boolean {
return when(mScrollOrientation) {
if (itemCount == 0) {
return false
}
return when (mScrollOrientation) {
ScrollOrientation.TOP_TO_BOTTOM, ScrollOrientation.BOTTOM_TO_TOP -> true
else -> false
}
}
override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
mLayout?.requestLayout()
removeAndRecycleAllViews(recycler)
mScrollOffset = getValidOffset(mScrollOffset)
loadItemView(recycler)
if (itemCount > 0) {
mScrollOffset = getValidOffset(mScrollOffset)
loadItemView(recycler)
}
}
override fun scrollHorizontallyBy(dx: Int, recycler: RecyclerView.Recycler, state: RecyclerView.State): Int {
@ -395,7 +407,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
private fun scrollToCenter(targetPosition: Int, recyclerView: RecyclerView, animation: Boolean) {
val targetOffset = getPositionOffset(targetPosition)
when(mScrollOrientation) {
when (mScrollOrientation) {
ScrollOrientation.LEFT_TO_RIGHT, ScrollOrientation.RIGHT_TO_LEFT -> {
if (animation) {
recyclerView.smoothScrollBy(targetOffset - mScrollOffset, 0)
@ -414,14 +426,14 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
}
private fun getValidOffset(expectOffset: Int): Int {
return when(mScrollOrientation) {
return when (mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.LEFT_TO_RIGHT -> Math.max(Math.min(width * (itemCount - 1), expectOffset), 0)
else -> Math.max(Math.min(height * (itemCount - 1), expectOffset), 0)
}
}
private fun getPositionOffset(position: Int): Int {
return when(mScrollOrientation) {
return when (mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT -> position * width
ScrollOrientation.LEFT_TO_RIGHT -> (itemCount - 1 - position) * width
ScrollOrientation.BOTTOM_TO_TOP -> position * height
@ -439,6 +451,9 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
}
private fun getFirstVisibleItemMovePercent(): Float {
if (width == 0 || height == 0) {
return 0f
}
return when (mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT -> (mScrollOffset % width) * 1.0f / width
ScrollOrientation.LEFT_TO_RIGHT -> {
@ -465,7 +480,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
//当是 Fling 触发的时候
val triggerOrientation = mFlingOrientation
mFlingOrientation = FlingOrientation.NONE
when(mScrollOrientation) {
when (mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT -> {
if (triggerOrientation == FlingOrientation.RIGHT_TO_LEFT) {
return position + 1
@ -506,4 +521,4 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
position + 1
}
}
}
}