2013-10-09 50 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())); 
    }