2016-12-27 34 views
0

我想動畫查看它被添加到父級後(正如DrawerLayout)。問題是視圖大小不一,動畫目標位置取決於該大小。簡化的示例代碼:動畫新創建的未知大小的視圖

AnimatingView extends View { 
     public int offsetX; 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      final int screenWidth = MeasureSpec.getSize(widthMeasureSpec); 
      final int screenHeight = MeasureSpec.getSize(heightMeasureSpec); 
      offsetX = calculateOffset(screenWidth); 
      ... 
     } 
    } 

代碼與此類似觸發動畫:

@Override 
    public void onClick(View v) { 
     AnimatingView animatingView = new AnimatingView(getContext()); 
     parentLayout.addView(animatingView); 
     animatingView.animate().x(animatingView.offsetX).setDuration(500).start(); 
    } 

在這種情況下onMeasure()animate()後會發生,所以動畫失敗。做什麼取決於視圖測量的正確方法是什麼?

簡單的&愚蠢的方式會像animateOnceAfterMeasuring()基於isInitialized標誌,但我不認爲它是這樣做的正確方法。

+0

你爲什麼不u使用'Android版:在你的父佈局XML –

+0

放'animatingView.animate(animateLayoutChanges'屬性).x(animatingView.offsetX).setDuration(500).start();'parent line in parentLayout.post(new Runnable(){});' –

+0

@sohanshetty在這種情況下,父ViewGroup會將孩子佈置在默認位置,而不是在小孩實際上應該停止它的動作的位置nt – Levinthann

回答

1

可以使用ViewTreeObserver此

@Override 
public void onClick(View v) { 
    final AnimatingView animatingView = new AnimatingView(getContext()); 
    parentLayout.addView(animatingView); 
    animatingView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 
      if (Build.VERSION.SDK_INT < 16) { 
       animatingView.getViewTreeObserver().removeGlobalOnLayoutL‌​istener(this); 
      } else { 
       animatingView.getViewTreeObserver().removeOnGlobalLayoutList‌​ener(this); 
      } 
      animatingView.animate().x(animatingView.offsetX).setDuration(500).start(); 
     } 
    }); 
} 
+1

你應該全球佈局後刪除此監聽器: '如果(Build.VERSION.SDK_INT <16){ \t \t \t animatingView.getViewTreeObserver()removeGlobalOnLayoutListener(本); } else { animatingView.getViewTreeObserver()。removeOnGlobalLayoutListener(this); }' – RadekJ

+0

對不起,我錯過了,會更新答案 – Premsuraj

2

這應該工作:

AnimatingView animatingView = new AnimatingView(getContext()); 
    parentLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 
      @Override 
      public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 
       v.removeOnLayoutChangeListener(this); 
       animatingView.animate().x(animatingView.offsetX).setDuration(500).start(); 
      } 
     });