2011-12-13 162 views
8

我開發了一個基於ViewGroup的控件,我的問題是我需要在動畫結束後保存項目的位置。我在我創建的AnimationListener的動畫對象中調用了setFillAfter(true),在onAnimationEnd方法調用View.layout(l,t,r,b)中設置了動畫後的位置,因爲我希望動畫在下一次從新項目的位置開始。但在這種情況下,它看起來像項目佈局兩次。如果我在動畫結束時不使用View.layout(l,t,r,b),則下一個動畫將從上一個位置開始。這裏是我的代碼:動畫結束後更改視圖位置

private void scrollUp() { 
    for(int i = 0; i < getChildCount(); i++) { 
     final View child = getChildAt(i); 
     final int index = i; 
     final int newleft = child.getLeft() + mOffsetBetweenItems; 
     final int newTop = child.getTop() - mOffsetBetweenItems; 
     TranslateAnimation scrollUp = new TranslateAnimation(0, mOffsetBetweenItems, 0, -mOffsetBetweenItems);   
     scrollUp.setDuration(1500); 
     scrollUp.setFillAfter(true);   
     scrollUp.setAnimationListener(
      new AnimationListener() { 

       @Override 
       public void onAnimationStart(Animation animation) {} 

       @Override 
       public void onAnimationRepeat(Animation animation) {} 

       @Override 
       public void onAnimationEnd(Animation animation) { 
        child.layout(newleft, newTop, newleft + child.getMeasuredWidth(), newTop + child.getMeasuredHeight()); 
       } 
      } 
     ); 

     child.startAnimation(scrollUp); 
    } 
} 

請給我一個建議,我應該如何重置視圖的位置相應的動畫的結束位置?

+0

改變位置意味着您想在佈局中將其設置在BOTTOM或TOP中,您希望像這樣.. –

+0

不是BOTTOM或TOP,而是在具體的X,Y座標中,這些座標由'view.lay out()'方法 – teoREtik

回答

12

我做到了。下面是代碼:

private void scrollUp() { 
    for(int i = 0; i < getChildCount(); i++) { 
     final View child = getChildAt(i); 
     final int index = i; 
     final int newleft = child.getLeft() + mOffsetBetweenItems; 
     final int newTop = child.getTop() - mOffsetBetweenItems; 
     TranslateAnimation scrollUp = new TranslateAnimation(0, mOffsetBetweenItems, 0, -mOffsetBetweenItems);   
     scrollUp.setDuration(1500); 
     scrollUp.setFillEnabled(true);   
     scrollUp.setAnimationListener(
      new AnimationListener() { 

       @Override 
       public void onAnimationStart(Animation animation) {} 

       @Override 
       public void onAnimationRepeat(Animation animation) {} 

       @Override 
       public void onAnimationEnd(Animation animation) { 
        child.layout(newleft, newTop, newleft + child.getMeasuredWidth(), newTop + child.getMeasuredHeight()); 
       } 
      } 
     ); 

     child.startAnimation(scrollUp); 
    } 
} 

只是刪除setFillAfter(true),寫setFillEnabled(true)代替。但在這種情況下,我不明白setFillEnabled()工作的邏輯,因爲它提供的行爲不像文檔中描述的那樣。

+0

在onAnimationEnd設置新的左側我的問題。謝謝。在你的代碼中,什麼時候mOffsetBetweenItems被設置/更新? – speedynomads

+0

注意:至少不適用於棒棒糖(猜測在某些API級別,它是偶然實現的,但是至少在棒棒糖上肯定無效) – MDragon00

0

反轉你的動畫;首先讓您的視圖處於新位置,然後從舊位置移動到新位置。

+0

如果我先給出一個新的位置,它會立即將我的視圖重新繪製到新位置 – teoREtik

+0

如果您在更改位置後立即調用startAnimation(),則不適用。 – Jave

+0

如果我在'view.startAnimation()'之前調用'View.layout()',它會重繪我的視圖並從新位置開始動畫 – teoREtik

19

您必須使用ObjectAnimator,它從API 11級別開始工作。它改變自動查看位置,

這裏是例子

ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX); 
objectAnimator.setDuration(1000); 
objectAnimator.start(); 

感謝JUL他answer

如果沒有找到object animator您的應用程序,改變從Project -> properties -> Android API級別,比import android.animation.ObjectAnimator;

+0

它動畫化視圖。對象動畫器不會更改視圖座標。 – mertsimsek