2013-10-09 48 views
1

我目前有一個按鈕,當點擊一個動畫開始,顯示按鈕上方的LinearLayout。 LinearLayout直接在它之上。在xml文件中,LinearLayouts可見性設置爲GONE。所以當按鈕被點擊時,可見性被設置爲可見。然後動畫開始。動畫是一個滑動的動畫。一切都很完美。但是當按鈕被點擊時,按鈕跳轉到LinearLayout結束的底部。即使LinearLayout仍在經歷動畫。如何使LinearLayout動畫的按鈕移動?我希望一切都能平穩過渡。但按鈕跳躍,看起來不太平滑。動態動畫 - Android

的LinearLayout動畫

<?xml version="1.0" encoding="utf-8"?> 
<!-- slide down --> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fillAfter="true"> 

    <scale 
     android:duration="500" 
     android:fromXScale="1.0" 
     android:fromYScale="0.0" 
     android:interpolator="@android:anim/linear_interpolator" 
     android:toXScale="1.0" 
     android:toYScale="1.0" /> 

</set> 

回答

2

我今天遇到了一個非常類似的情況。

我使用了一個自定義動畫來重新調整視圖大小。

測量並保存所需的高度。最初,高度設置爲0,並隨着動畫的繼續而增長。最後達到測量的高度,然後將其設置爲原樣包裝內容。

public static void expand(final View v) { 
    v.measure(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); 
    final int targetHeight = v.getMeasuredHeight(); 

    v.getLayoutParams().height = 0; 
    v.setVisibility(View.VISIBLE); 
    Animation a = new Animation() 
    { 
     @Override 
     protected void applyTransformation(float interpolatedTime, Transformation t) { 
      v.getLayoutParams().height = interpolatedTime == 1 
        ? LayoutParams.WRAP_CONTENT 
        : (int)(targetHeight * interpolatedTime); 
      v.requestLayout(); 
     } 

     @Override 
     public boolean willChangeBounds() { 
      return true; 
     } 
    }; 

    // 1dp/ms 
    a.setDuration((int)(targetHeight/v.getContext().getResources().getDisplayMetrics().density)); 
    v.startAnimation(a); 
} 

v應該是您想要製作動畫的LinearLayout。 你可以選擇固定的持續時間,如果你preffer。

來源:https://stackoverflow.com/a/13381228/1646326

0

使用自定義動畫,這是非常容易的,你可以改變任何你在applytransformation想, interpolatedTime - 這就像%,從開始到結束動畫當前位置(並具有浮動從0到值1,所以這裏使用這個interpolatedTime你可以遍歷任何你能想象);)

static class HeightAnimation extends Animation{ 
     private View view; 
     private int mViewHeightFrom; 
     private int mViewHeightTo; 



     public HeightAnimation(View view, int heightFrom, int heightTo){ 
      this.view = view; 
      this.mViewHeightFrom = heightFrom; 
      this.mViewHeightTo = heightTo; 

     } 

     @Override 
     protected void applyTransformation(float interpolatedTime, Transformation t) { 
      RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int)((mViewHeightTo - mViewHeightFrom)*interpolatedTime+0.5)); 
      view.setLayoutParams(params); 
     } 

     @Override 
     public boolean willChangeBounds() { 
      return true; 
     } 

     @Override 
     public boolean isFillEnabled() { 
      return true; 
     } 
    } 

與用法:

public static void applyAnimationHeightTransformation(Context context, View view, int viewHeightFrom, int viewHeightTo, int duration, int animationOffsetMilisec){ 
     HeightAnimation anim = new HeightAnimation(view, viewHeightFrom, viewHeightTo); 
     anim.setStartOffset(animationOffsetMilisec); 
     anim.setDuration(duration); 
     //anim.setInterpolator(new OvershootInterpolator()); // here interpolators can be used 
     if(view != null) { 
      view.setAnimation(anim); 
      view.startAnimation(anim); 
     } 
    } 

用於使高度更容易使用 - 通過轉換爲像素在dp中使用值:

public static int dpToPx(int dp) { 
     return (int)(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, YourApplication.getMainContext().getResources().getDisplayMetrics())); 
    }