Follow treslines by email clicking Here!

Tuesday, June 10, 2014

How to implement a spring feder like animation to your horizontal scroll view android

Hi there!

Today i'm gonna share something very useful and nice to see. Imagine you have a horizontal scroll view with a linearlayout inside of it containing some tools (icons) to be shown to the user. Well, in some cases, it is very userfriendly to let the user scroll thru the icons in the horizontal.

Ok till now there is nothing new on it right? But what about if you wanna implement a feder like movement. Let's say either you show five icons or you try to scroll and the tool(scrollview) will jump smoothly to the next five tools in the scrollview. (something like a pagination)

That's interesting right? well, let's see how i did it. It's for sure not the ultimate way, but it works very well for my needs and it may work for you as well.

Here is the code:


import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

/**
 * paginates icons on a given horizontal scroll view.
 * @author Ricardo Ferreira
 * @version 1.0
 * @since 05/04/2014
 */
public class HorizontalPaginationScroller implements OnTouchListener {

    private HorizontalScrollView horizontal;
    private LinearLayout container;
    private View[] views;
    private boolean hasPaged = false;

    /** Assuming your application's orientation is portrait and the 
     * scrollbar is placed on the bottom with 7 itens to be shown*/
    public HorizontalPaginationScroller(HorizontalScrollView scrollview) {
        assert (scrollview != null);
        assert (scrollview.getChildCount() > 0);
        assert (scrollview.getChildAt(0) != null);
        assert (scrollview.getChildAt(0) instanceof LinearLayout);
        assert (((LinearLayout) horizontal.getChildAt(0)).getChildCount() > 0);

        this.horizontal = scrollview;
        this.horizontal.setOnTouchListener(this);

        container = (LinearLayout) horizontal.getChildAt(0);
        views = new View[container.getChildCount()];
        for (int i = 0; i < views.length; i++) {
            assert(container.getChildAt(i)!=null);
            views[i] = container.getChildAt(i);
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            boolean[] isVisible =  new boolean[views.length];
            setVisibility(isVisible);
            if(isVisible[0]&&isVisible[5] && !hasPaged || !isVisible[0]&&isVisible[5] && !hasPaged){
                pageRight();
                break;
            }
            if(isVisible[4]&&isVisible[5]&&isVisible[6]||isVisible[0]&&isVisible[5]&&!isVisible[6] && hasPaged){
                pageLeft();
                break;
            }
            break;
        default:
            break;
        }
        return false;
    }

    private void pageLeft() {
        hasPaged=false;
        horizontal.post(new Runnable() {
            @Override
            public void run() {
                horizontal.smoothScrollTo(0, 0);
            }
        });
    }

    private void pageRight() {
        hasPaged=true;
        horizontal.post(new Runnable() {
            @Override
            public void run() {
                horizontal.smoothScrollTo(horizontal.getWidth(), 0);
            }
        });
    }

    private void setVisibility(boolean[] child) {
        for (int i = 0; i < views.length; i++) {
            // check if children (views) showing to user are visible
            Rect scrollBounds = new Rect();// NOPMD
            horizontal.getHitRect(scrollBounds);
            if (views[i].getLocalVisibleRect(scrollBounds)) {
                child[i]=true;
            }else{
                child[i]=false;
            }
        }
    }
}


How to use it:

in the onCreate method from your application call:

new HorizontalPaginationScroller((HorizontalScrollView)findViewById(R.id.yourScrollView)); 

That's all. Hope you like it!