Search code examples
androidanimationviewflipper

Viewflipper animation doesn't work on first swipe


On my main activity, I have a viewflipper with three child views. After the app is first started, when I do the first right to left swipe, the view changes, but it does not have the slide animation. After the first swipe, the animation works as expected when swiping in either direction. I am following this tutorial. The code I use is:

 public boolean onTouchEvent(MotionEvent touchevent)
{
    switch (touchevent.getAction())
    {
        // when user first touches the screen
        case MotionEvent.ACTION_DOWN:
        {
            lastX = touchevent.getX();
            break;
        }
        case MotionEvent.ACTION_UP:
        {
            float currentX = touchevent.getX();

            // left to right swipe
            if (lastX < currentX)
            {
                if (mViewFlipper.getDisplayedChild() == 0)
                    break;

                mViewFlipper.setInAnimation(this, R.anim.in_from_left);
                mViewFlipper.setOutAnimation(this, R.anim.out_to_right);

                mViewFlipper.showPrevious();
            }

            // right to left swipe
            if (lastX > currentX)
            {
                if (mViewFlipper.getDisplayedChild() == mViewFlipper.getChildCount() - 1)
                    break;

                mViewFlipper.setInAnimation(this, R.anim.in_from_right);
                mViewFlipper.setOutAnimation(this, R.anim.out_to_left);

                mViewFlipper.showNext();
            }

            break;
        }
    }

    return false;
}

When I debug the code, I don't see any differences between when the animation is working and when it isn't. Also, I see this behavior on an actual device and the emulator. What did I miss? I can post the animation xml files and the view xml, if they are needed.

EDIT:

The only way I am able to get this to work as expected is to set the following in the onCreate method:

   mViewFlipper.setInAnimation(this, R.anim.in_from_right);
    mViewFlipper.setOutAnimation(this, R.anim.out_to_left);
    mViewFlipper.setFlipInterval(10000);
    mViewFlipper.startFlipping();

I then call stopFlipping() on the first swipe. The interesting thing to me is that the animation works on the first swipe with these changes, even if the first auto-flip hasn't occurred. However, if I simply set the animation in the onCreate method without calling the startFlipping() method, it still doesn't have the animation on the first swipe. Can someone offer an explanation as to why this behavior occurs?


Solution

  • Looking through the ViewFlipper class's source code, the ViewFlipper.showNext() internally calls the ViewAnimator.showOnly(int position) method.

    This is the validation performed inside that method:

       void showOnly(int childIndex) {
            final boolean animate = (!mFirstTime || mAnimateFirstTime);
            showOnly(childIndex, animate);
       }
    

    So, in order to achieve what you want, you'll need to tell the ViewFlipper to animate the first flip inside your Activity.onCreate:

        @Override
        void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.my_activity);
            mViewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
            mViewFlipper.setAnimateFirstView(true);
       }
    

    NOTE:

    I was able to achieve this without calling mViewFlipper.setAnimateFirstView(true) using API level 22. But it doesn't seem to work the same on previous versions.