Viewflipper动画在第一次滑动时不起作用

10

在我的主活动上,我有一个带有三个子视图的ViewFlipper。在应用程序首次启动后,当我进行第一次从右向左的滑动时,视图会改变,但它没有滑动动画效果。在第一次滑动后,在任何方向上滑动时,动画效果都按预期工作。我正在遵循这篇教程。我使用的代码是:

 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;
}

当我调试代码时,我没有看到动画工作和不工作之间的任何区别。而且,我在实际设备和模拟器上都看到了这种行为。我错过了什么?如果需要,我可以发布动画xml文件和视图xml。

编辑:

我能够使其按预期工作的唯一方法是在onCreate方法中设置以下内容:

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

然后我在第一次滑动时调用stopFlipping()方法。有趣的是,即使第一次自动翻转尚未发生,使用这些更改时动画也会在第一次滑动时起作用。但是,如果我只是在onCreate方法中设置动画而没有调用startFlipping()方法,则第一次滑动仍然没有动画效果。有人能解释一下为什么会出现这种行为吗?


只是为了检查,在查看 ViewFlipper 类的源代码时,当您调用 ViewFlipper.showNext() 方法时,将会调用 ViewAnimator.showOnly(int position) 方法。这是该方法内部执行的验证: final boolean animate = (!mFirstTime || mAnimateFirstTime); showOnly(childIndex, animate);。因此,可能发生的情况是第一次翻转时动画被简单地忽略了。我不确定,但您可以通过在 onCreate 中添加 mViewFlipper.setAnimateFirstView(true) 来检查它(而不是您在编辑中的那些行)。 - mmark
我有机会的时候会尝试一下。 - Matt M
@mmark 那个方法可行。把它作为答案发布,我会接受的。谢谢! - Matt M
3个回答

2

起初,你没有真正的onTouchEvent算法。现在你得到了一些类似于反转的东西,并且设置了错误的动画顺序。

尝试使用我的onTouchEvent,这对我非常有效:

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

                // if left to right swipe on screen
                if (lastX < currentX)
                {
                    // If no more View/Child to flip
                    if (viewFlipper.getDisplayedChild() == 0)
                        break;

                    // set the required Animation type to ViewFlipper
                    // The Next screen will come in form Left and current Screen will go OUT from Right
                    viewFlipper.setInAnimation(this, R.anim.in_from_left);
                    viewFlipper.setOutAnimation(this, R.anim.out_to_right);
                    // Show the next Screen
                    viewFlipper.showNext();
                }

                // if right to left swipe on screen
                if (lastX > currentX)
                {
                    if (viewFlipper.getDisplayedChild() == 1)
                        break;
                    // set the required Animation type to ViewFlipper
                    // The Next screen will come in form Right and current Screen will go OUT from Left
                    viewFlipper.setInAnimation(this, R.anim.in_from_right);
                    viewFlipper.setOutAnimation(this, R.anim.out_to_left);
                    // Show The Previous Screen
                    viewFlipper.showPrevious();
                }
                break;
            }
        }
        return true;
    }

我已经做出了更改,但结果仍然相同。在第一次滑动时,没有动画效果。之后的每次滑动,动画都能正常工作。 - Matt M
1
我不这么认为,因为动画效果是可以工作的,只是在第一次滑动时没有。请看我的编辑。 - Matt M
1
试试在另一部手机上,也许你的手机上有一些动画问题? - Sheraz Ahmad Khilji
1
我已经尝试了实际设备和模拟器。两者表现出相同的行为。 - Matt M

1

浏览ViewFlipper类的源代码,ViewFlipper.showNext() 内部调用了 ViewAnimator.showOnly(int position) 方法。

这是该方法内部执行的验证:

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

因此,为了实现您想要的效果,您需要在 Activity.onCreate 中告诉 ViewFlipper 在第一次翻转时进行动画:
    @Override
    void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);
        mViewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
        mViewFlipper.setAnimateFirstView(true);
   }

注意:

在API 22及以上版本中,我成功地实现了这一点,而不需要调用mViewFlipper.setAnimateFirstView(true)。但在之前的版本中似乎无法正常工作。


0
Try to use this gesture for swipe with animation just get animation swipe left to right and right to left and put inside this:

   final GestureDetector gesture = new GestureDetector(getActivity(),
                new GestureDetector.SimpleOnGestureListener() {

                    @Override
                    public boolean onDown(MotionEvent e) {
                        return true;
                    }

                    @Override
                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                            float velocityY) {
                        Log.i("null", "onFling has been called!");
                        final int SWIPE_MIN_DISTANCE = 80;
                        final int SWIPE_MAX_OFF_PATH = 150;
                        final int SWIPE_THRESHOLD_VELOCITY = 100;
                        try {
                            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                                return false;
                            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                                try {

                                  //your swipe code 
                                } catch (Exception e) {
                                    n = -1;
                                }

                            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                                try {

//your swipe code 
                         } catch (Exception e) {

                                }

                            }
                        } catch (Exception e) {
                        }
                        return super.onFling(e1, e2, velocityX, velocityY);
                    }
                });
        yourFullRelativeLayout.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gesture.onTouchEvent(event);
            }
        });
        yourView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gesture.onTouchEvent(event);
            }
        });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接