2011-10-16 27 views
19

का उपयोग कर एंड्रॉइड में एक 3 डी फ्लिप एनीमेशन बनाना this android tutorial का उपयोग करके मैंने एक दृश्य का 3 डी फ्लिप बनाया है, हालांकि, मैंने इसे प्रोग्रामेटिक रूप से किया है और यदि संभव हो तो मैं इसे एक्सएमएल में करना चाहता हूं। मैं बस बीच में एक दृश्य को कम करने और फिर वापस जाने के बारे में बात नहीं कर रहा हूं, लेकिन एक वास्तविक 3 डी फ्लिप।एक्सएमएल

क्या यह xml के माध्यम से संभव है?

उत्तर

54

यहां जवाब है, हालांकि यह केवल 3.0 और ऊपर के साथ काम करता है।

1) "एनिमेटर" नामक एक नया संसाधन फ़ोल्डर बनाएं।

2) एक नई .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> 

नहीं, ऑब्जेक्टएनिमीटर टैग अपरकेस "ओ" से शुरू नहीं होता है।

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

ओम 252345 द्वारा ट्यूटोरियल या लिंक विश्वसनीय 3 डी फ्लिप का उत्पादन नहीं करता है। वाई-अक्ष पर एक साधारण रोटेशन आईओएस में नहीं किया जाता है। उस अच्छा फ्लिप महसूस करने के लिए ज़ूम प्रभाव की भी आवश्यकता है। इसके लिए, this example पर एक नज़र डालें। एक वीडियो here भी है।

+0

मुझे एहसास है कि सवाल xml का उपयोग करते हुए android.com उदाहरण में y-axis rotation को कैसे बनाया जाए। लेकिन मुझे लगा कि शायद आप इसमें भी रुचि रखते हैं। – 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

यह अच्छा है, लेकिन कस्टम एनीमेशन कार्यों पर भरोसा नहीं करना बेहतर होगा, लेकिन इसके बजाय ऑब्जेक्टएनिमीटर। कारण बेहतर समर्थन और उलटापन है। –

+1

@ तुषार पांडे: - दिमागी रोशनी .. क्या जवाब .. grt dude –

18

चूंकि इस प्रश्न के उत्तर काफी दिनांकित हैं, तो वैल्यूएनिमीटर पर निर्भर एक और आधुनिक समाधान है। यह समाधान एक सच्चे, दृश्यमान आकर्षक 3 डी-फ्लिप को लागू करता है, क्योंकि यह न केवल दृश्य को फिसलता है, बल्कि फ़्लिपिंग के दौरान इसे स्केल करता है (इस प्रकार ऐप्पल यह करता है)।

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

यह है कि

पहले हम ValueAnimator की स्थापना की!

इस स्थापना के बाद आप

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

मैं आपके एल्गोरिदम को एक्सएमएल ट्विन एनीमेशन में अनुवाद करने की कोशिश कर रहा हूं। मैं यह नहीं समझ सकता कि पिवोटएक्स और पिवोटि गुणों को सही तरीके से कैसे सेट किया जाए: क्या आपको कोई विचार है? –

+1

@AntonioSesto क्षमा करें, मैं ज्यादातर एक्सएमएल के बिना एनिमेट करता हूं क्योंकि मुझे कोड में एनिमेटिंग अधिक बहुमुखी लगता है। मुझे लगता है कि एक्सएमएल में पिवट स्थापित करना मुश्किल होगा, क्योंकि आप दृश्य आयामों को नहीं जानते हैं। हो सकता है कि आप इसे प्रतिशत के रूप में सेट कर सकें, क्या आपने पिवट को 50% पी जैसे कुछ करने की कोशिश की है? –

+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); 
    
    उपयोग कर रहा है

    धाराप्रवाह इंटरफ़ेस का उपयोग करके आप अधिक जटिल और रोमांचक एनीमेशन बना सकते हैं। ईजी। आप हार्डवेयर त्वरण को सक्षम कर सकते हैं बस कॉलर() विधि (एपीआई 16) के साथ कॉल करें। अधिक here

  2. आप 3 डी झटका एनीमेशन बनाने के लिए कैसे पता लगाने के लिए चाहते हैं, here और here

  3. का पालन करें मैं केवल एक अनुसंधान के लिए अपने खुद के समाधान implemended। इसमें शामिल हैं: रद्द करना, त्वरण, समर्थन API> = 15 और Property Animation पर आधारित है। संपूर्ण एनीमेशन में प्रत्येक पक्ष के लिए 4 भाग, 2 शामिल हैं। प्रत्येक ऑब्जेक्टएनिमीटर में एक श्रोता होता है जो वर्तमान एनीमेशन इंडेक्स को परिभाषित करता है और ऑनएनीमेशन कैंसल पर ऑनएनिशन स्टार्ट और वर्तमान प्ले टाइम मान में एक छवि का प्रतिनिधित्व करता है। ऐसा लगता है कि

    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 :) –