Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@JafarKhQ
Last active January 12, 2022 12:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JafarKhQ/e9128d67eee9d522a54e to your computer and use it in GitHub Desktop.
Save JafarKhQ/e9128d67eee9d522a54e to your computer and use it in GitHub Desktop.
A Custom ViewPager for Android with an option to make it swipe to left only, swipe to right only or completely disbale the swipe
import android.content.Context;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
public class CustomSwipeableViewPager extends ViewPager {
private static final String TAG = "CustomSwipeableViewPager";
private static final float MIN_SWIPE_DISTANCE = 30.0f;
public static enum SwipeType {
DISABLED, TO_LEFT, TO_RIGHT, ENABLED
}
private SwipeType mSwipeType;
private GestureDetectorCompat mGestureDetector;
public CustomViewPager(Context context) {
super(context);
myInitViewPager();
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
myInitViewPager();
}
private void myInitViewPager() {
mSwipeType = SwipeType.ENABLED;
mGestureDetector = new GestureDetectorCompat(getContext(), simpleOnGestureListener);
mGestureDetector.setIsLongpressEnabled(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (mSwipeType) {
case DISABLED:
return false;
case ENABLED:
return super.onTouchEvent(event);
default:
return mGestureDetector.onTouchEvent(event) && super.onTouchEvent(event);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
switch (mSwipeType) {
case DISABLED:
return false;
default:
return super.onInterceptTouchEvent(event);
}
}
public void setSwipeType(SwipeType swipeType) {
mSwipeType = swipeType;
}
private GestureDetector.SimpleOnGestureListener simpleOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
final float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) < MIN_SWIPE_DISTANCE) {
return true;
}
if (diffX > 0) {
// Swipe to Left
return SwipeType.TO_LEFT == mSwipeType;
} else {
// Swipe to Right
return SwipeType.TO_RIGHT == mSwipeType;
}
}
};
}
@Alex159357
Copy link

Alex159357 commented Sep 30, 2021

It dos not working (((
line 102 e1 and e2 always null

@Alex159357
Copy link

I fix some errors and post here working example if some body will need to use it

typealias OnSwipeLeft = (position: Int?) -> Unit
typealias OnSwipeRight = (position: Int?) -> Unit
typealias OnSwipe = (position: Int?) -> Unit

class ViewPagerXX : ViewPager {
private var mSwipeType: SwipeType? = null
private var mGestureDetector: GestureDetectorCompat? = null
private var flag = false
private var currentPage = 0
var onSwipeLeft: OnSwipeLeft? = null
var onSwipeRight: OnSwipeRight? = null
var onSwipe: OnSwipe? = null
var event: MotionEvent? = null

constructor(context: Context?) : super(context!!) {
    init()
}

constructor(context: Context?, attrs: AttributeSet?) : super(
    context!!, attrs
) {
    init()
}

fun init() {
    mSwipeType = SwipeType.ENABLED
    mGestureDetector = GestureDetectorCompat(this.context, simpleOnGestureListener)
    mGestureDetector!!.setIsLongpressEnabled(true)
}

override fun onPageScrolled(position: Int, offset: Float, offsetPixels: Int) {
    currentPage = position
    super.onPageScrolled(position, offset, offsetPixels)
}

override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
    var isAllowed = mGestureDetector!!.onTouchEvent(ev)
    return when (mSwipeType) {
        SwipeType.DISABLED -> false
        else -> if (isAllowed) super.onInterceptTouchEvent(ev) else flag
    }
}

fun setSwipeType(swipeType: SwipeType?) {
    mSwipeType = swipeType
}

private val simpleOnGestureListener: GestureDetector.SimpleOnGestureListener =
    object : GestureDetector.SimpleOnGestureListener() {

        override fun onDown(e: MotionEvent): Boolean {
            return true
        }

        override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
            return true
        }

        override fun onSingleTapUp(e: MotionEvent): Boolean {
            return true
        }

        override fun onDoubleTap(e: MotionEvent): Boolean {
            return true
        }

        override fun onDoubleTapEvent(e: MotionEvent): Boolean {
            return true
        }

        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent?,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            return true
        }

        override fun onScroll(
            e1: MotionEvent?,
            e2: MotionEvent?,
            distanceX: Float,
            distanceY: Float
        ): Boolean {
            if (e1 != null && e2 != null) {
                val diffX = e2.x - e1.x
                if (abs(diffX) < MIN_SWIPE_DISTANCE) {
                    return true
                }
                return if (diffX > 0) {
                    // Swipe to Left
                    onSwipe?.invoke(this@ViewPagerXX.currentItem)
                    onSwipeLeft?.invoke(this@ViewPagerXX.currentItem)
                    SwipeType.TO_LEFT == mSwipeType
                } else {
                    // Swipe to Right
                    onSwipe?.invoke(this@ViewPagerXX.currentItem)
                    onSwipeRight?.invoke(this@ViewPagerXX.currentItem)
                    SwipeType.TO_RIGHT == mSwipeType
                }
            } else {
                Log.d("EventState", "NULL")
                return false
            }
        }

    }


enum class SwipeType {
    DISABLED, TO_LEFT, TO_RIGHT, ENABLED
}
companion object {
    private const val MIN_SWIPE_DISTANCE = 30.0f
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment