2012-02-09 24 views
17

क्या एक ही समय में कई विचारों को एनिमेट करने का कोई तरीका है?एकल एनिमेशन - एकाधिक दृश्य

मैं 5 TextViews और 4 रंग की धारियां (एक पृष्ठभूमि के साथ सादे RelativeLayouts) है:

मुझे क्या करना चाहते हैं एनिमेशन का अनुवाद है। एनिमेशन की शुरुआत में, स्टैप्स को क्षैतिज पंक्ति में टेक्स्ट व्यू के साथ रखा जाता है। अंत में मैं सभी TextViews पट्टियों के बीच खड़ी हैं:

enter image description here

यह एक बहुत ही सरल ड्राइंग है, लेकिन यह प्रदर्शित करता है कि मुझे क्या करना चाहते हैं। क्या एनिमेशन के साथ ऐसा करने का कोई तरीका है, या मुझे कैनवास एनिमेशन का उपयोग करना है।

उत्तर

4

अपनी एनीमेशन ऑब्जेक्ट्स बनाएं, फिर एक ही समय में सभी दृश्यों पर startAnimation सामूहिक रूप से उपयोग करें। तो यह कुछ इस तरह होगा:

TranslateAnimation anim1; 
TranslateAnimation anim2; 
TranslateAnimation anim3; 

// Setup the animation objects 

public void startAnimations() 
{ 
    //... collect view objects 
    view1.startAnimation(anim1); 
    view2.startAnimation(anim2); 
    view3.startAnimation(anim3); 
} 

बस ध्यान दें कि अधिक एनिमेशन आप एक बार में चल रहा है, धीमी यह हो रहा है।

+1

उपयोग कर सकते हैं यह उनके कारण नहीं होगा (यहाँ आवश्यक नहीं) सिंक्रनाइज़ेशन से बाहर होने के लिए , विशेष रूप से वे जो बाद में शुरू कर रहे हैं? – Matthew

+0

वास्तव में नहीं। असल में क्या होता है जब आप किसी दृश्य पर 'startAnimation' का उपयोग करते हैं, तब तक यह वांछित स्थान तक पहुंचने तक स्वयं को अमान्य करना शुरू कर देता है। जब आप इसे एक ही समय में सभी विचारों पर कॉल करते हैं, तो वे सभी अपने आप को 'अवैध() 'पर कॉल करेंगे, फिर अगले ड्राइंग पास पर प्रत्येक दृश्य उनके अगले फ्रेम में खींचा जाएगा। चूंकि आप इसे यूआई थ्रेड पर वैसे भी बुला रहे हैं, तब तक कोई भी एनिमेशन तब तक शुरू नहीं होगा जब तक आप उस विधि से वापस नहीं आ जाते। नोट: प्री-हनीकॉम्ब एनीमेशन फ्रेमवर्क का उपयोग केवल दृश्य के दृश्य भाग को ले जाता है।उपयोगकर्ता उस पर क्लिक करने में सक्षम नहीं होगा। – DeeV

+0

मैं anim1.setFillAfter (सत्य) के साथ एनिमेशन लागू करता हूं; और फिर लेआउट पैराम्स का उपयोग कर वास्तव में दृश्य को स्थानांतरित करने के लिए? (मुझे बस कोशिश करनी चाहिए, लेकिन इसके देर से :) – Matthew

3

मैं कई दृश्य के बीच में एक भी एनीमेशन उदाहरण साझा करने के लिए प्रबंधित किया है। कम से कम अल्फाएनीमेशन के साथ। मेरे पास एक सूची दृश्य और एक एनीमेशन था जिसे सभी सूची आइटम दृश्यों के किसी विशेष बच्चे पर लागू किया जाना चाहिए। मेरे मामले में किसी भी समय साझा एनीमेशन 'जुड़ने' और 'छोड़ने' के विचारों के लिए संभव होना चाहिए और इसे किसी अन्य तरीके से अन्य एनिमेटेड दृश्यों को प्रभावित नहीं करना चाहिए या पहले से चल रहे एनीमेशन में हस्तक्षेप नहीं करना चाहिए। इसे प्राप्त करने के लिए मुझे एंड्रॉइड के स्टॉक अल्फाएनीमेशन की एक समायोजित प्रतिलिपि बनाना पड़ा। मेरा उपयोग केस अपेक्षाकृत विशेष है, लेकिन अगर किसी को ListView के साथ समान लक्ष्य से निपटना है तो इसे यहां रहने दें।

/** 
* This class is a copy of android's stock AlphaAnimation with two adjustments: 
* - fromAlpha, toAlpha and duration are settable at any time. 
* - reset() method can be blocked. Reason: view.setAnimation() calls animation's reset() method 
* which is not intended in our use case. 
* For every new list item view we call setAnimation once for it's life time 
* and animation should not be reset because it is shared by all list item views and may be in progress. 
*/ 
public class MutableAlphaAnimation extends Animation { 
    private float mFromAlpha; 
    private float mToAlpha; 
    private boolean resetBlocked; 

    public MutableAlphaAnimation() { 
    } 

    public void start(float fromAlpha, float toAlpha, long duration) { 
     mFromAlpha = fromAlpha; 
     mToAlpha = toAlpha; 
     setDuration(duration); 
     setStartTime(START_ON_FIRST_FRAME); 
    } 

    public void setResetBlocked(boolean resetBlocked) { 
     this.resetBlocked = resetBlocked; 
    } 

    @Override 
    public void reset() { 
     if (! resetBlocked) super.reset(); 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     final float alpha = mFromAlpha; 
     t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime)); 
    } 

    @Override 
    public boolean willChangeTransformationMatrix() { 
     return false; 
    } 

    @Override 
    public boolean willChangeBounds() { 
     return false; 
    } 
} 

एक दृश्य के लिए इस एनीमेशन सेट करने के लिए:

  animation.setResetBlocked(true); 
      view.setAnimation(animation); 
      animation.setResetBlocked(false); 

और एक एनीमेशन (पहले setAnimation द्वारा निर्धारित) शुरू करने के लिए दो बातें किया जाना चाहिए:

 animation.start(0.0f, 1.0f, FADE_IN_DURATION); 

और उसके बाद आप एनीमेशन द्वारा प्रभावित हर दृश्य पर मैन्युअल रूप से अमान्य() को कॉल करना होगा।

सामान्य प्रारंभएनीमेशन() आपके लिए अमान्य() करता है, लेकिन सेटएनीमेशन नहीं है। (एंड्रॉइड के स्रोतों में View.setAnimation() विधि पर टिप्पणी पढ़ें)।

49

आप इस प्रकार कई दृश्य एनिमेट के लिए ObjectAnimator उपयोग कर सकते हैं:

ArrayList<ObjectAnimator> arrayListObjectAnimators = new ArrayList<ObjectAnimator>(); //ArrayList of ObjectAnimators 

ObjectAnimator animY = ObjectAnimator.ofFloat(view, "y", 100f); 
arrayListObjectAnimators.add(animY); 

ObjectAnimator animX = ObjectAnimator.ofFloat(view, "x", 0f); 
arrayListObjectAnimators.add(animX); 
... 
ObjectAnimator[] objectAnimators = arrayListObjectAnimators.toArray(new ObjectAnimator[arrayListObjectAnimators.size()]); 
AnimatorSet animSetXY = new AnimatorSet(); 
animSetXY.playTogether(objectAnimators); 
animSetXY.setDuration(1000);//1sec 
animSetXY.start(); 
+2

एकमात्र नकारात्मकता यह है कि यह संस्करण 11 (हनीकॉम) – Matthew

+3

से नया है, एपीआई को सभी तरह से वापस लाने के लिए नौल्डैंड्रॉइड का उपयोग करें (http://nineoldandroids.com/) – Tushar

+0

+1 यह दिखाने के लिए कि उन्हें सभी को एक साथ कैसे लॉन्च किया जाए –

0

आप AnimationSet

AnimatorSet decSet2 = new AnimatorSet(); 
     decSet2.playTogether(
       ObjectAnimator.ofFloat(view, "x",dX), 
       ObjectAnimator.ofFloat(view, "y",dY), 
       ObjectAnimator.ofFloat(mTextCancel, "x",dX), 
       ObjectAnimator.ofFloat(mTextCancel, "y", dY), 
       ObjectAnimator.ofArgb(mBtnOne, "visibility", View.VISIBLE, View.GONE), 
       ); 
     decSet2.setDuration(0); 
     decSet2.start(); 
संबंधित मुद्दे