2011-10-16 182 views

回答

54

下面是答案,但它只適用於3.0及以上版本。

1)創建一個名爲「animator」的新資源文件夾。

2)創建一個新的.xml文件,我將稱之爲「翻轉」。使用以下xml代碼:

<?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> 

不,objectAnimator標記不以大寫字母「O」開頭。

3)用下面的代碼啓動動畫:

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(); 

我得到這一切都源自here

+0

@RAS感謝鏈接庫。 :)也許下次它可以進入評論而不是編輯我的答案?我對這個圖書館一無所知,所以把它歸因於我並不完全正確。感謝您的輸入! –

+0

我明白你的觀點,即沒有人不喜歡某人在未經允許的情況下編輯他/她的帖子。但這個答案不是我編輯的。它由其他人編輯,我只是​​批准它並解決了編輯你的答案的人所犯的語法錯誤。如果您想查看,請點擊「編輯」旁邊顯示的日期/時間,位於我的姓名和徽標上方。您可以在那裏看到完整的修訂歷史記錄。 – RAS

+5

要使用下面的3.0代碼,請使用以下lib:https://github.com/JakeWharton/NineOldAndroids。用戶貢獻:http://stackoverflow.com/users/1117511/loks –

4

該教程或om252345的鏈接不會產生可信的3D翻轉。在Y軸上進行簡單的旋轉並不是在iOS中完成的。縮放效果也需要創建一個很好的翻轉感覺。爲此,請查看this example。 還有一個視頻here

+0

我意識到問題在於如何使用xml在android.com示例中製作y軸旋轉。但我想,也許你也對此感興趣。 – Ephraim

7

我創建了一個簡單的程序,如創建的視圖翻轉:

enter image description here

在活動你必須創建這個方法,在視圖中添加flip_rotation。

private void applyRotation(View view) 
{ 
    final Flip3dAnimation rotation = new Flip3dAnimation(view); 
    rotation.applyPropertiesInRotation(); 
    view.startAnimation(rotation); 
} 

爲此,您必須複製用於提供flip_rotation的主類。

import android.graphics.Camera; 
import android.graphics.Matrix; 
import android.util.Log; 
import android.view.View; 
import android.view.animation.AccelerateInterpolator; 
import android.view.animation.Animation; 
import android.view.animation.Transformation; 

public class Flip3dAnimation extends Animation { 
    private final float mFromDegrees; 
    private final float mToDegrees; 
    private final float mCenterX; 
    private final float mCenterY; 
    private Camera mCamera; 

    public Flip3dAnimation(View view) { 
     mFromDegrees = 0; 
     mToDegrees = 720; 
     mCenterX = view.getWidth()/2.0f; 
     mCenterY = view.getHeight()/2.0f; 
    } 

    @Override 
    public void initialize(int width, int height, int parentWidth, 
      int parentHeight) { 
     super.initialize(width, height, parentWidth, parentHeight); 
     mCamera = new Camera(); 
    } 

    public void applyPropertiesInRotation() 
    { 
     this.setDuration(2000); 
     this.setFillAfter(true); 
     this.setInterpolator(new AccelerateInterpolator()); 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     final float fromDegrees = mFromDegrees; 
     float degrees = fromDegrees 
       + ((mToDegrees - fromDegrees) * interpolatedTime); 

     final float centerX = mCenterX; 
     final float centerY = mCenterY; 
     final Camera camera = mCamera; 

     final Matrix matrix = t.getMatrix(); 

     camera.save(); 

     Log.e("Degree",""+degrees) ; 
     Log.e("centerX",""+centerX) ; 
     Log.e("centerY",""+centerY) ; 

     camera.rotateY(degrees); 

     camera.getMatrix(matrix); 
     camera.restore(); 

     matrix.preTranslate(-centerX, -centerY); 
     matrix.postTranslate(centerX, centerY); 

    } 

} 
+0

這很好,但最好不要依賴自定義動畫功能,而要使用ObjectAnimators。原因是更好的支持和可逆性。 –

+1

@Tushar Pandey: - mindblowing ..什麼答案.. grt dude –

18

由於這個問題的答案相當過時,所以這裏是一個更爲現代的依賴於ValueAnimators的解決方案。 這個解決方案實現了一個真正的,視覺上吸引人的3D翻轉,因爲它不僅翻轉視圖,而且在翻轉時調整視角(蘋果公司就是這麼做的)。

首先,我們成立了ValueAnimator:

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

和相應的更新監聽器:

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

這就是它!

此設置後,您可以通過調用

mFlipAnimator.start(); 

翻轉的意見,如果你想檢查視圖翻轉,實現並調用通過調用

mFlipAnimator.reverse(); 

反向翻轉功能:

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

您還可以檢查視圖是否正在翻轉平安通過實施此方法:

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

您可以結合上述功能來實現一個不錯的功能切換翻轉,這取決於它是否被翻轉與否:

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

這就是它!簡單而簡單。請享用!

+0

我想將你的算法轉換成XML補間動畫。我無法弄清楚如何正確設置pivotX和pivotY屬性:你有什麼想法嗎? –

+1

@AntonioSesto對不起,我大多是沒有xml的動畫,因爲我發現代碼中的動畫更加多才多藝。我認爲在xml中設置數據透視將會很困難,因爲您不知道視圖尺寸。也許你可以將它設置爲百分比,但是,你是否嘗試將關鍵點設置爲50%p? –

+1

這太棒了,謝謝! – Leon

4

一個更好的解決辦法翻轉與停止使用該資源的動畫形象,是如下: -

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(); 
3
  1. 做到這一點最簡單的方法是使用ViewPropertyAnimator

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

    使用流暢的界面,您可以構建更復雜和令人興奮的動畫。 例如您可以使用Layer()方法(API 16)調用硬件加速。更多here

  2. 如果你想弄清楚如何創建3D動畫輕彈,請按照herehere

  3. 我implemended自己的解決方案僅用於研究。它包括:取消,加速,支持API> = 15,並基於Property Animation。整個動畫包括4個部分,每邊2個。 每個objectAnimator都有一個偵聽器,該偵聽器定義當前動畫索引並在onAnimationCancel中表示onAnimationStart中的圖像和當前播放時間值。 它看起來像

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

    關於啓動組通話

    mAnimatorSet.play(mQuarterAnim1).before(mQuarterAnim2) 
    

    如果AnimatorSet被取消,我們可以計算出三角洲和運行反向動畫依靠當前索引動畫和當前播放時間值。

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

    完整的例子here

+0

不錯的一個解釋@ yoAlex5 +1 :) –