Creating a 3D flip animation in Android using XML

后端 未结 8 1765
萌比男神i
萌比男神i 2020-12-22 20:25

I have created a 3D flip of a view using this android tutorial However, I have done it programmatically and I would like to do it all in xml, if possible. I am not talking

8条回答
  •  死守一世寂寞
    2020-12-22 21:02

    Since the answers to this question are fairly dated, here is a more modern solution relying on ValueAnimators. This solution implements a true, visually appealing 3D-flip, because it not just flips the view, but also scales it while it is flipping (this is how Apple does it).

    First we set up the ValueAnimator:

    mFlipAnimator = ValueAnimator.ofFloat(0f, 1f);
    mFlipAnimator.addUpdateListener(new FlipListener(frontView, backView));
    

    And the corresponding update listener:

    public class FlipListener implements ValueAnimator.AnimatorUpdateListener {
    
        private final View mFrontView;
        private final View mBackView;
        private boolean mFlipped;
    
        public FlipListener(final View front, final View back) {
            this.mFrontView = front;
            this.mBackView = back;
            this.mBackView.setVisibility(View.GONE);
        }
    
        @Override
        public void onAnimationUpdate(final ValueAnimator animation) {
            final float value = animation.getAnimatedFraction();
            final float scaleValue = 0.625f + (1.5f * (value - 0.5f) * (value - 0.5f));
    
            if(value <= 0.5f){
                this.mFrontView.setRotationY(180 * value);
                this.mFrontView.setScaleX(scaleValue);
                this.mFrontView.setScaleY(scaleValue);
                if(mFlipped){
                    setStateFlipped(false);
                }
            } else {
                this.mBackView.setRotationY(-180 * (1f- value));
                this.mBackView.setScaleX(scaleValue);
                this.mBackView.setScaleY(scaleValue);
                if(!mFlipped){
                    setStateFlipped(true);
                }
            }
        }
    
        private void setStateFlipped(boolean flipped) {
            mFlipped = flipped;
            this.mFrontView.setVisibility(flipped ? View.GONE : View.VISIBLE);
            this.mBackView.setVisibility(flipped ? View.VISIBLE : View.GONE);
        }
    }
    

    That's it!

    After this setup you can flip the views by calling

    mFlipAnimator.start();
    

    and reverse the flip by calling

    mFlipAnimator.reverse();
    

    If you want to check if the view is flipped, implement and call this function:

    private boolean isFlipped() {
        return mFlipAnimator.getAnimatedFraction() == 1;
    }
    

    You can also check if the view is currently flipping by implementing this method:

    private boolean isFlipping() {
        final float currentValue = mFlipAnimator.getAnimatedFraction();
        return (currentValue < 1 && currentValue > 0);
    }
    

    You can combine the above functions to implement a nice function to toggle the flip, depending on if it is flipped or not:

    private void toggleFlip() {
        if(isFlipped()){
            mFlipAnimator.reverse();
        } else {
            mFlipAnimator.start();
        }
    }
    

    That's it! Simple and easy. Enjoy!

提交回复
热议问题