2015-10-07 22 views
1

我有一個FrameLayout容器,我試圖讓它的動畫變化。我在視圖上調用了container.setLayoutTransition(layoutTransition),但是當我稍後調用container.removeView(v)時,DISAPPEARING動畫未執行,視圖立即被刪除。LayoutTransition.DISAPPEARING動畫在移除子視圖時不運行

這裏是我的過渡代碼:

LayoutTransition layoutTransition = new LayoutTransition(); 
layoutTransition.setAnimator(LayoutTransition.APPEARING, 
    ObjectAnimator.ofFloat(null, View.TRANSLATION_Y, toolHeight, 0f)); 
layoutTransition.setStartDelay(LayoutTransition.APPEARING, 0); 
layoutTransition.setDuration(LayoutTransition.APPEARING, 1000); 
layoutTransition.setAnimator(LayoutTransition.DISAPPEARING, 
    ObjectAnimator.ofFloat(null, View.TRANSLATION_Y, 0f, toolHeight)); 
layoutTransition.setStartDelay(LayoutTransition.DISAPPEARING, 0); 
layoutTransition.setDuration(LayoutTransition.DISAPPEARING, 1000); 
container.setLayoutTransition(layoutTransition); 

並交換意見我這樣做:

if (container.getChildCount() > 0) { 
    for (int i = container.getChildCount() - 1; i >= 0; i--) { 
    container.removeViewAt(i); 
    } 
} 
container.addView(newView); 

我放慢了動畫確認的情況下,我可以清楚地看到APPEARING轉換正確執行,但DISAPPEARING轉換不是,該視圖只是立即刪除。

我發現,如果我從LayoutTransition.removeChild()方法中刪除視圖,但它會增加一些似乎不必要的複雜度。這就是變成:

if (container.getChildCount() > 0) { 
    final View v = container.getChildAt(0); 
    container.getLayoutTransition().removeChild(container, v); 
    container.getLayoutTransition().addTransitionListener(new LayoutTransition.TransitionListener() { 
    @Override 
    public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) { 
    } 

    @Override 
    public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) { 
     transition.removeTransitionListener(this); 
     if (transitionType == LayoutTransition.DISAPPEARING) { 
     container.removeView(view); 
     } 
    } 
    } 
} 
container.addView(newView); 

認爲這很糟糕?這只是爲了一次刪除單個視圖,如果容器中有多個視圖,那麼我必須添加一個轉換監聽器來計算執行時間以知道何時刪除自己,這只是一團糟。

刪除本身很有趣,因爲如果我只是簡單地將該轉換偵聽器放在LayoutTransition上,並且它不會自行刪除,那麼消失的轉換不會再次運行。

很明顯,我錯過了有關使刪除過渡執行的東西。任何幫助,將不勝感激。

編輯

它已經向我指出,加入意見取消DISAPPEARING轉換:

public class ViewGroup { 
    private void addViewInner(...) { 
    if (mTransition != null) { 
     // Don't prevent other add transitions from completing, but cancel remove 
     // transitions to let them complete the process before we add to the container 
     mTransition.cancel(LayoutTransition.DISAPPEARING); 
    } 
    } 
} 

這沒有很大的意義對我來說。不知道這裏的推理是什麼。

回答

3

正如您已經注意到的,LayoutTransition並沒有像一些較新的API那樣對動畫類型進行真正的排序。它旨在一次處理單個項目更改。最乾淨的代碼將來自測序與延遲添加你自己,而不是鏈接偵聽器調用:

if (container.getChildCount() > 0) { 
    for (int i = container.getChildCount() - 1; i >= 0; i--) { 
    container.removeViewAt(i); 
    } 

    //Start the add once removals are complete 
    long duration = 
    container.getLayoutTransition().getDuration(LayoutTransition.DISAPPEARING); 
    container.postOnAnimationDelayed(new Runnable(){ 
    @Override 
    public void run() { 
     container.addView(newView); 
    } 
    }, duration); 
} else { 
    container.addView(newView); 
} 

你可能會得到更好的編排出來的Scenes這樣的事情,但是這是API 19+

+0

如果我必須這樣做,使用自動刪除的LayoutTransitionListener來「計劃」添加會更好嗎? – rharter

+0

正如您所提到的那樣,難點在於必須級聯移除偵聽器或計算事務以瞭解它們何時全部完成。這是一種讓代碼少得多的「足夠接近」的方法。 – Devunwired