Creating a 3D flip animation in Android using XML

后端 未结 8 1729
萌比男神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 20:40

    Just put the view which you're going to animate it in place of viewToFlip.

    ObjectAnimator flip = ObjectAnimator.ofFloat(viewToFlip, "rotationY", 0f, 360f); // or rotationX
    flip.setDuration(2000); // 2 seconds
    flip.start();
    
    0 讨论(0)
  • 2020-12-22 20:42

    Here is the answer, though it only works with 3.0 and above.

    1) Create a new resources folder called "animator".

    2) Create a new .xml file which I will call "flipping". Use the following xml code:

    <?xml version="1.0" encoding="utf-8"?>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:valueFrom="0" android:valueTo="360" android:propertyName="rotationY" >
    </objectAnimator>
    

    No, the objectAnimator tags do not start with an uppercase "O".

    3) Start the animation with the following code:

    ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(mContext, R.animator.flipping); 
    anim.setTarget(A View Object reference goes here i.e. ImageView);
    anim.setDuration(3000);
    anim.start();
    

    I got all this from here.

    0 讨论(0)
  • 2020-12-22 20:49

    One of the better solution to flip the image with out use of the resource animation , is as follow:-

      ObjectAnimator animation = ObjectAnimator.ofFloat(YOUR_IMAGEVIEW, "rotationY", 0.0f, 360f);  // HERE 360 IS THE ANGLE OF ROTATE, YOU CAN USE 90, 180 IN PLACE OF IT,  ACCORDING TO YOURS REQUIREMENT 
    
      animation.setDuration(500); // HERE 500 IS THE DURATION OF THE ANIMATION, YOU CAN INCREASE OR DECREASE ACCORDING TO YOURS REQUIREMENT
      animation.setInterpolator(new AccelerateDecelerateInterpolator());
      animation.start();
    
    0 讨论(0)
  • 2020-12-22 20:55

    The tutorial or the link by om252345 don't produce believable 3D flips. A simple rotation on the y-axis isn't what's done in iOS. The zoom effect is also needed to create that nice flip feel. For that, take a look at this example. There is also a video here.

    0 讨论(0)
  • 2020-12-22 20:59
    1. The simplest way to do it is using ViewPropertyAnimator

      mImageView.animate().rotationY(360f);
      

      Using the fluent interface you can build more complex and exciting animation. E.g. you can enable hardware acceleration just call withLayer() method(API 16). More here

    2. If you want to figure out how to create 3d flick animation, please follow here and here

    3. I implemended my own solution only for a research. It includes: cancelation, accelleration, support API >= 15 and is based on Property Animation. The entire animation includes 4 parts, 2 for each side. Every objectAnimator has a listener that defines current animation index and represents an image in the onAnimationStart and current play time value in the onAnimationCancel. It looks like

      mQuarterAnim1.addListener(new AnimatorListenerAdapter() {
          @Override
          public void onAnimationStart(Animator animation) {
              mQuarterCurrentAnimStartIndex = QUARTER_ANIM_INDEX_1;
              mImageView.setImageResource(mResIdFrontCard);
          }
      
          @Override
          public void onAnimationCancel(Animator animation) {
              mQuarterCurrentAnimPlayTime = ((ObjectAnimator) animation).getCurrentPlayTime();
          }
      });
      

      For start set call

      mAnimatorSet.play(mQuarterAnim1).before(mQuarterAnim2)
      

      If AnimatorSet was canceled we can calculate delta and run the reverse animation relying on the current index animation and the current play time value.

      long degreeDelta = mQuarterCurrentAnimPlayTime * QUARTER_ROTATE / QUARTER_ANIM_DURATION;
      
      if (mQuarterCurrentAnimStartIndex == QUARTER_ANIM_INDEX_1) {
          mQuarterAnim4.setFloatValues(degreeDelta, QUARTER_FROM_1);
          mQuarterAnim4.setDuration(mQuarterCurrentAnimPlayTime);
      
          mAnimatorSet.play(mQuarterAnim4);
      }
      

    A full code snippet you can find here

    0 讨论(0)
  • 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!

    0 讨论(0)
提交回复
热议问题