Search code examples
androidimagescrollpagination

Android horizontal scrollview behave like iPhone (paging)


I have a LinearLayout inside a HorizontalScrollView. The content is just a image. While scrolling, I need to achieve the same behavior you get when setting the paging option on a the iPhone equivalent of the HSW (scrolling the list should stop at every page on the list, not continue moving).

How is this done in Android? Should I implement this features by myself or there is a particular property to set or a subclass of HSV to implement?


Solution

  • So, my solution is:

    1. Intercept the onTouch event and calculate whether the page should change to the next or keep on the current
    2. Inherit from HorizontalScrollView and override the method computeScroll

    The method computeScroll the called to move the list. By default I suppose it's implemented to decelerate with a certain ratio... Since I don't want this motion, I just override it without specifing a body.

    The code for the event handler is:

    _scrollView.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(event.getAction() == MotionEvent.ACTION_UP)
                {
                    float currentPosition = _scrollView.getScrollX();
                    float pagesCount = _horizontalBar.getChildCount();
                    float pageLengthInPx = _horizontalBar.getMeasuredWidth()/pagesCount;
                    float currentPage = currentPosition/pageLengthInPx;
    
                    Boolean isBehindHalfScreen =  currentPage-(int)currentPage > 0.5;
    
                    float edgePosition = 0;
                    if(isBehindHalfScreen)
                    {
                        edgePosition = (int)(currentPage+1)*pageLengthInPx;
                    }
                    else
                    {
                        edgePosition = (int)currentPage*pageLengthInPx;
                    }
    
                    _scrollView.scrollTo((int)edgePosition, 0);
                }
    
                return false;
            }
        });
    

    And in my inherited HorizontalScrollView

    @Override
        public void  computeScroll  (){
            return;
        }