In Part 1 of of Creating an Android Image Slider Control, we built out the ImageSlider class, but when you added this class to a View, the horizontal scrolling didn’t behave well. In order to resolve the scrolling issue, we started playing with the Gesture options and listeners. We tried implementing the onFling event, but we did not receive consistent behavior on my older Samsung device. As a result we opted for handling the TouchEvent in our own code,

@Override
    public boolean onTouchEvent(MotionEvent ev) {
        super.onTouchEvent( ev );
    	final int action = MotionEventCompat.getActionMasked(ev); 
        
        switch (action) { 
        
	        case MotionEvent.ACTION_DOWN: {
	            final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
	              
	            // Remember where we started (for dragging)
	            touchX = MotionEventCompat.getX(ev, pointerIndex);
	            touchY = MotionEventCompat.getY(ev, pointerIndex);
	            distanceX = 0;
	            distanceY = 0;
	            
	            // Save the ID of this pointer (for dragging)
	            mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
	            break;
	        }
	        
	        case MotionEvent.ACTION_MOVE: {
	            // Find the index of the active pointer and fetch its position
	            final int pointerIndex = 
	                    MotionEventCompat.findPointerIndex(ev, mActivePointerId);  
	                
	            final float x = MotionEventCompat.getX(ev, pointerIndex);
	            final float y = MotionEventCompat.getY(ev, pointerIndex);
	                
	            // Calculate the distance moved
	            distanceX += x - touchX;
	            distanceY += y - touchY;

	            invalidate();

	            // Remember this touch position for the next move event
	            touchX = x;
	            touchY = y;

	            break;
	        }
	                
	        case MotionEvent.ACTION_CANCEL: {
	        	final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
	            final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); 
	        	
	            if (pointerId == mActivePointerId) {
	            	mActivePointerId = INVALID_POINTER_ID;
	            	
	            	//i need to know if the movement in X was bigger than the movement in Y.
	            	if( Math.abs(distanceX) > Math.abs(distanceY) ){
		            	if(distanceX > 0){
		            		onSwipeRight();
		            	}else if(distanceX < 0){
		            		onSwipeLeft();
		            	}
	            	}
	            }
	            break;
	        }
            
        }       
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // Do not allow touch events.
        return false;
    }
    
    public void onSwipeRight(){
    	
    }
    
    public void onSwipeLeft(){
    	
    }

Handling the onTouch and onInterceptTouch events cancels the scrolling behavior of the component and allows us to add a new behavior that will scroll item by item. We implement our own scrolling logic in a moveToSlide function.

pub

public void moveToSlide(int index){
	//let's ignore movement to images outside the bounds of the slider
    	if(index < 0 || index >= images.size()){
    		return;
    	}
    	this.currentSelectedIndex = index;
    	int childX = Math.round( layout.getChildAt(index).getX() );
    	this.smoothScrollTo(childX, 0);
}
    
public int getCurrentSlide(){
    	return this.currentSelectedIndex;
}

public void onSwipeRight(){
    	moveToSlide( getCurrentSlide() - 1);
}
    
public void onSwipeLeft(){
    	moveToSlide( getCurrentSlide() + 1);
}

In our next post, we’ll resolve the scenarios where the ImageViews are wider than the actual screen size, and complete the Image Carousel.