Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@JakeSteam
Last active September 7, 2018 17:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakeSteam/d69275118bd47984e94ee40d00aee219 to your computer and use it in GitHub Desktop.
Save JakeSteam/d69275118bd47984e94ee40d00aee219 to your computer and use it in GitHub Desktop.
"Dynamically preventing scrolling on selected ViewPager pages" for blog.jakelee.co.uk
<com.example.LockableViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
import android.content.Context
import android.support.v4.view.ViewPager
import android.util.AttributeSet
import android.view.MotionEvent
enum class SwipeDirection { BOTH, LEFT, RIGHT, NONE }
// https://stackoverflow.com/a/34076649/608312
class LockableViewPager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {
private var initialXValue: Float = 0f
private var direction: SwipeDirection? = null
init {
this.direction = SwipeDirection.BOTH
}
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (this.isSwipeAllowed(event)) {
super.onTouchEvent(event)
} else false
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return if (this.isSwipeAllowed(event)) {
super.onInterceptTouchEvent(event)
} else false
}
private fun isSwipeAllowed(event: MotionEvent): Boolean {
if (this.direction === SwipeDirection.BOTH) {
return true
} else if (direction === SwipeDirection.NONE) {
return false
}
if (event.action == MotionEvent.ACTION_DOWN) {
initialXValue = event.x
return true
}
if (event.action == MotionEvent.ACTION_MOVE) {
try {
val diffX = event.x - initialXValue
if (diffX > 0 && direction === SwipeDirection.RIGHT) {
// swipe from left to right detected
return false
} else if (diffX < 0 && direction === SwipeDirection.LEFT) {
// swipe from right to left detected
return false
}
} catch (e: Exception) {
e.printStackTrace()
}
}
return true
}
fun setAllowedSwipeDirection(direction: SwipeDirection) {
this.direction = direction
}
}
private fun pageChangeListener(): ViewPager.SimpleOnPageChangeListener =
object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
setSwipeability()
}
}
private fun setSwipeability() {
pager.setAllowedSwipeDirection(getSwipeDirection(pager))
}
override fun getSwipeDirection(pager: LockableViewPager): SwipeDirection {
if (isUserRequired(pager.currentItem)) {
return SwipeDirection.NONE
}
val isFirstUser = pager.currentItem == 0
val isLastUser = pager.currentItem == pager.adapter!!.count - 1
val isUserToLeft = !isFirstUser && pager.currentItem > 0
val isUserToRight = !isLastUser && pager.currentItem < pager.adapter!!.count - 1
val isOptionalUserOnLeft = isUserToLeft && !isUserRequired(pager.currentItem - 1)
val isOptionalUserOnRight = isUserToRight && !isUserRequired(pager.currentItem + 1)
if (isOptionalUserOnLeft && isOptionalUserOnRight) {
return SwipeDirection.BOTH
} else if (isOptionalUserOnLeft) {
return SwipeDirection.LEFT
} else if (isOptionalUserOnRight) {
return SwipeDirection.RIGHT
} else {
return SwipeDirection.NONE
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment