2011-03-07 13 views
9

से पहले देरी को कैसे खत्म कर सकता हूं मैं हनीकॉम में नई LayoutTransition कक्षा को आजमाने की कोशिश कर रहा हूं। मैंने एक एनीमेशन सेट किया है जो को ViewGroup पर जोड़ते समय स्थान पर स्लाइड करता है। मैंने देखा कि जब कोई दृश्य पहली बार प्रस्तुत करता है और जब LayoutTransition.APPEARING एनीमेशन शुरू होता है तो थोड़ी देर (लगभग 20 मिमी) होती है। दूसरे शब्दों में, स्क्रीन पर दृश्य दिखाई देने के बाद, यह एक पल के लिए हवा में लटकता है, और फिर जगह में एनिमेट करना शुरू कर देता है। आप इसे ApiDemos नमूना प्रोजेक्ट में भी देख सकते हैं। लेआउट एनीमेशन उदाहरणों में, ViewGroup की अपरिवर्तनीय एनीमेशन शुरू होने से पहले हमेशा देरी होती है। मैंने अन्य LayoutTransition एनिमेशन को शून्य करने के लिए भी सेट करने का प्रयास किया है, या अंततः उन्हें बहुत कम अवधि दे रहा है, लेकिन फिर भी APPEARING एनीमेशन में देरी हो रही है। मैं APPEARING एनीमेशन से पहले देरी कैसे खत्म करने हैलेआउट ट्रांज़िशन एनीमेशन

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" android:layout_height="match_parent" 
    android:orientation="vertical"> 
    <Button android:layout_width="wrap_content" 
     android:layout_height="wrap_content" android:text="Add Button" 
     android:id="@+id/addNewButton" /> 
    <LinearLayout android:orientation="vertical" 
     android:layout_width="match_parent" android:layout_height="match_parent" 
     android:id="@+id/frame_container" android:animateLayoutChanges="true" /> 
</LinearLayout> 

: यहाँ मेरी कोड है:

public class DebugExampleFour extends Activity { 
    private int numButtons = 1; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.debug_example_four); 

     final ViewGroup frame = (ViewGroup) findViewById(R.id.frame_container); 
     LayoutTransition transitioner = new LayoutTransition(); 

     Animator appearingAnimation = ObjectAnimator.ofFloat(null, "translationX", 600, 0); 
     appearingAnimation.setDuration(45); 
     appearingAnimation.setStartDelay(0); 
     appearingAnimation.setInterpolator(new DecelerateInterpolator()); 
     appearingAnimation.addListener(new AnimatorListenerAdapter() { 
      public void onAnimationEnd(Animator anim) { 
       View view = (View) ((ObjectAnimator) anim).getTarget(); 
       view.setTranslationX(0f); 
      } 
     }); 
     transitioner.setAnimator(LayoutTransition.APPEARING, appearingAnimation); 
     Animator dummyAnimation = ObjectAnimator.ofInt(0, 1); 
     dummyAnimation.setDuration(1); 
     dummyAnimation.setStartDelay(0); 
     transitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, dummyAnimation); 
     transitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, dummyAnimation); 
     transitioner.setAnimator(LayoutTransition.DISAPPEARING, dummyAnimation); 

     frame.setLayoutTransition(transitioner); 

     Button addButton = (Button) findViewById(R.id.addNewButton); 
     addButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       Button newButton = new Button(DebugExampleFour.this); 
       newButton.setText("Click To Remove " + (numButtons++)); 
       newButton.setOnClickListener(new View.OnClickListener() { 
        public void onClick(View v) { 
         frame.removeView(v); 
        } 
       }); 
       frame.addView(newButton, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 

      } 
     });  
    } 

} 

यहाँ लेआउट फ़ाइल है कि उदाहरण के साथ चला जाता है?

उत्तर

27

दाएं - दोनों स्तरों पर देरी हो रही है। जब आप लेआउट ट्रांज़िशन के संदर्भ में एनीमेटर चला रहे हैं, तो आप लेयरट्रांसशन ऑब्जेक्ट पर अवधि निर्धारित करना चाहते हैं, अंतर्निहित एनीमेटर पर नहीं (क्योंकि संक्रमण ऑब्जेक्ट इन गुणों के लिए एनिमेटर्स को अपने मूल्यों की आपूर्ति करेगा रन)।

इसका कारण यह है कि लेआउट ट्रांसमिशन आम तौर पर एक कंटेनर के अंदर वस्तुओं पर चलने वाले एनिमेशन का अनुक्रम होने जा रहा है। तो, उदाहरण के लिए, यदि आप किसी ऑब्जेक्ट को किसी कंटेनर में 'प्रकट' करना चाहते हैं, तो संक्रमण पहले दूसरी ऑब्जेक्ट को रास्ते से एनिमेट करेगा, फिर नई वस्तु को जगह में एनिमेट करेगा। वस्तुओं की एक सेट के बीच में एक आइटम जोड़ने की कल्पना करें (जैसा कि आप एपीडीमोस ऐप्स में देखते हैं); यह पहले अंतरिक्ष बनाता है, फिर ऑब्जेक्ट को फीका करता है।

उपरोक्त मूल कोड के मामले में, आप तुरंत एनीमेशन को चलाने के लिए चाहते हैं, तो आपको संक्रमण शुरू करना चाहिए 0 के लिए अपील करने के लिए डेले (जैसा आपने किया था ऊपर जवाब)।

दूसरी तरफ, डिस्प्लेयरिंग एनीमेशन डिफ़ॉल्ट रूप से शुरू नहीं होता है, लेकिन CHANGE_DISAPPEARING एनीमेशन के प्रारंभ में डिस्प्लेयरिंग एनीमेशन की अवधि के बराबर है, इस धारणा के तहत कि आप पहले किसी आइटम को निकालना चाहते हैं, फिर अन्य आइटम को एनिमेट करें कंटेनर अपने नए स्थानों में।

चूंकि ये धारणाएं हैं जो हर स्थिति पर लागू नहीं होती हैं, इसलिए आपके विशिष्ट मामलों में काम करने के लिए आपको इसकी आवश्यकता के अनुसार व्यवहार को नियंत्रित करने के लिए लेआउट ट्रांज़िशन पर अवधि/प्रारंभ करें।

ध्यान दें कि यदि आप एनीमेशन प्रकारों में से कोई एक नहीं चलाना चाहते हैं, तो आपको उस एनीमेशन को शून्य पर सेट करना चाहिए (लेआउटट्रांसशन.सेटएनिमीटर (int, एनीमेटर) के लिए प्रलेखन देखें)। इसे अपने डमी पर सेट करने वाला एनीमेटर का असर नहीं होगा। एक बात के लिए, लेआउट ट्रांज़िशन पर डिफ़ॉल्ट अवधि/स्टार्ट डेले मान अभी भी लागू होंगे, भले ही आप इन एनिमेशन के लिए कस्टम एनीमेटर्स की आपूर्ति करें।

कुछ और इसके बारे में पता होना चाहिए: अंतर्निहित समय तंत्र (एंड्रॉइड के लिए, लेकिन मैंने कभी भी अन्य प्लेटफ़ॉर्म के लिए भी काम किया है) कुछ न्यूनतम रिज़ॉल्यूशन होने वाला है। तो आप '1' की अवधि निर्धारित करते हैं, जिसके परिणामस्वरूप उस एनीमेशन 1ms में समाप्त नहीं हो सकता है। इसके बजाए, यह एक फ्रेम के लिए चलाएगा, फिर अगले फ्रेम पर (आमतौर पर सिस्टम को अच्छी तरह से व्यवहार किए गए एप्लिकेशन में रीफ्रेश दर अगर सिस्टम को बंद नहीं किया जाता है) तो यह देखेंगे कि एनीमेशन समाप्त होना चाहिए।

+0

@Chet को स्पष्ट करने के लिए धन्यवाद, मुझे लगता है कि जावाडोक में या आधिकारिक डेवलपर ब्लॉग पर आपकी पोस्ट में उल्लिखित इन अंतर्निहित देरी को देखना उपयोगी होगा। –

+0

अच्छा विचार - मैं डिफ़ॉल्ट व्यवहार/देरी के बारे में बात करने के लिए लेआउट ट्रांजिशन javadocs में कुछ जोड़ दूंगा। –

+0

..... चेट ने सिर्फ मेरे डिजिटल को छुआ ..... – dell116

7

यह Animator और LayoutTransition दोनों में से प्रत्येक का प्रारंभ विलंब मूल्य है। Animator प्रारंभ विलंब पहले ही शून्य है, इसलिए बदलना इससे मदद नहीं करता है। अजीब बात यह है कि LayoutTransition के लिए प्रारंभ में देरी कम से कम LayoutTransition.APPEARING के मामले में शून्य से अधिक प्रतीत होती है। यहां कामकाजी कोड है:

public class DebugExampleFour extends Activity { 
    private int numButtons = 1; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.debug_example_four); 

     final ViewGroup frame = (ViewGroup) findViewById(R.id.frame_container); 
     LayoutTransition transitioner = new LayoutTransition(); 

     Animator appearingAnimation = ObjectAnimator.ofFloat(null, "translationX", 600, 0); 
     appearingAnimation.addListener(new AnimatorListenerAdapter() { 
      public void onAnimationEnd(Animator anim) { 
       View view = (View) ((ObjectAnimator) anim).getTarget(); 
       view.setTranslationX(0f); 
      } 
     }); 
     transitioner.setAnimator(LayoutTransition.APPEARING, appearingAnimation); 
     transitioner.setDuration(LayoutTransition.APPEARING, 300); 
     transitioner.setStartDelay(LayoutTransition.APPEARING, 0); 

     frame.setLayoutTransition(transitioner); 

     Button addButton = (Button) findViewById(R.id.addNewButton); 
     addButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       Button newButton = new Button(DebugExampleFour.this); 
       newButton.setText("Click To Remove " + (numButtons++)); 
       newButton.setOnClickListener(new View.OnClickListener() { 
        public void onClick(View v) { 
         frame.removeView(v); 
        } 
       }); 
       frame.addView(newButton, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 

      } 
     });  
    } 
} 
संबंधित मुद्दे