2016-12-27 57 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(); 
      } 
     });