Brown
Brown

Reputation: 141

Android Viewpager bounce to half a page

So what i am trying to achieve is user would open to first page of the view pager, and the view pager would bounce to half of the second page and bounce back to the fist page indicating that there are more pages to scroll to. I was wondering on how i could implement this?

Upvotes: 8

Views: 4923

Answers (3)

Fish
Fish

Reputation: 261

Thank you Yuvraj! It worked with a simple modification. If anybody is getting "Invalid index 0, size is 0" error, here's a simple fix for it. If you call animateViewPager() method in onCreate() you might get this error, "Invalid index 0, size is 0". I believe viewpager.beginFakeDrag(); is being called before viewPager items / childs are initialized. So, call animateViewPager() with a delay like so:

new Handler().postDelayed(() -> animateViewPager(viewPager, 10, 1000), 500);

500 is the delay in milisecond

Upvotes: 0

Zen
Zen

Reputation: 2728

Adding a note to @Yuraj's answer. Call the method in onWindowFocusChanged when hasFocus==true as follows to avoid indexOutOfBoundsException:

@Override
public void onWindowFocusChanged(boolean hasFocus) 
{
    super.onWindowFocusChanged(hasFocus);

    if(hasFocus)
    {
        Handler handler = new Handler();

        final Runnable r = new Runnable() 
        {
            public void run() 
            {
                if(mViewPager.getCurrentItem() == 0)
                {
                    Context context = Activity_main.this;
                    String filename="Init";
                    SharedPreferences stats;
                    stats = context.getSharedPreferences(filename, 0); 
                    int appOpen = stats.getInt("appOpen", 0);

                    if(appOpen <= 5)
                    {
                        animateViewPager(mViewPager, 10, 300);

                        appOpen += 1;
                        SharedPreferences.Editor editor = stats.edit();
                        editor.putInt("appOpen", appOpen);
                        editor.commit();
                    }
                }
            }
        };

        handler.postDelayed(r, WAIT_VIEWPAGER_NUDGE);

    }
}

Upvotes: 1

Yuraj
Yuraj

Reputation: 3195

You can use fakeDragBy method to achieve this effect:

viewPager.beginFakeDrag();
viewPager.fakeDragBy(offset); //offset in pixels. 
viewPager.endFakeDrag();

EDIT:

I have made method for this:

private int animFactor;
private ValueAnimator animator = new ValueAnimator();

private void animateViewPager(final ViewPager pager, final int offset, final int delay) {
    if (!animator.isRunning()) {
        animator.removeAllUpdateListeners();
        animator.removeAllListeners();
        //Set animation
        animator.setIntValues(0, -offset);
        animator.setDuration(delay);
        animator.setRepeatCount(1);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = animFactor * (Integer) animation.getAnimatedValue();
                if (!pager.isFakeDragging()) {
                    pager.beginFakeDrag();
                }
                pager.fakeDragBy(value);
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationStart(Animator animation) {
                animFactor = 1;
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                pager.endFakeDrag();
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                animFactor = -1;
            }
        });
        animator.start();
    }
}

Example of usage:

animateViewPager(pager, 10, 1000);

Edit2: ValueAnimator is class for Api level 11. Also set pager adapter before calling this method.

Upvotes: 21

Related Questions