Android:展开/折叠动画

Android:展开/折叠动画

假设我有一个垂直线性Layout:

[v1][v2]

默认情况下,v1已经明显地=消失了。我想用扩展动画显示v1,同时按下v2。

我试过这样的方法:

Animation a = new Animation(){
    int initialHeight;

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final int newHeight = (int)(initialHeight * interpolatedTime);
        v.getLayoutParams().height = newHeight;
        v.requestLayout();
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        initialHeight = height;
    }

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

但是有了这个解决方案,当动画开始的时候,我会眨眼。我认为这是因为v1在动画应用之前显示了完整的尺寸。

对于javascript,这是jQuery的一行!用Android做这件事有什么简单的方法吗?


Qyouu
浏览 1767回答 3
3回答

温温酱

我看到这个问题很受欢迎,所以我贴出了我的实际解决方案。主要的优点是您不需要知道扩展的高度才能应用动画,并且一旦视图被展开,如果内容发生变化,它就会适应高度。对我来说很管用。public static void expand(final View v) {     int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(), View.MeasureSpec.EXACTLY);     int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);     v.measure(matchParentMeasureSpec, wrapContentMeasureSpec);     final int targetHeight = v.getMeasuredHeight();     // Older versions of android (pre API 21) cancel animations for views with a height of 0.     v.getLayoutParams().height = 1;     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;         }     };     // Expansion speed of 1dp/ms     a.setDuration((int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));     v.startAnimation(a);}public static void collapse(final View v) {     final int initialHeight = v.getMeasuredHeight();     Animation a = new Animation()     {         @Override         protected void applyTransformation(float interpolatedTime, Transformation t) {             if(interpolatedTime == 1){                 v.setVisibility(View.GONE);             }else{                 v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);                 v.requestLayout();             }         }         @Override         public boolean willChangeBounds() {             return true;         }     };     // Collapse speed of 1dp/ms     a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));     v.startAnimation(a);}正如@Jefferson在评论中所提到的,您可以通过更改动画的持续时间(以及速度)来获得更流畅的动画。目前,它已被设置为1dp/ms。

不负相思意

我试图做一个我认为是非常相似的动画,并找到了一个优雅的解决方案。此代码假定您总是从0->h或h->0(h是最大高度)。这三个构造函数参数是view=要动画的视图(在我的示例中是webview)、Target tHL.8=视图的最大高度,以及down=指定方向的布尔值(true=展开、false=折叠)。public class DropDownAnim extends Animation {     private final int targetHeight;     private final View view;     private final boolean down;     public DropDownAnim(View view, int targetHeight, boolean down) {         this.view = view;         this.targetHeight = targetHeight;         this.down = down;     }     @Override     protected void applyTransformation(float interpolatedTime, Transformation t) {         int newHeight;         if (down) {             newHeight = (int) (targetHeight * interpolatedTime);         } else {             newHeight = (int) (targetHeight * (1 - interpolatedTime));         }         view.getLayoutParams().height = newHeight;         view.requestLayout();     }     @Override     public void initialize(int width, int height, int parentWidth,             int parentHeight) {         super.initialize(width, height, parentWidth, parentHeight);     }     @Override     public boolean willChangeBounds() {         return true;     }}

慕沐林林

我今天在同一个问题上绊倒了,我想这个问题的真正解决办法是<LinearLayout&nbsp;android:id="@+id/container"android:animateLayoutChanges="true"...&nbsp;/>您必须为所有最顶层的布局设置此属性,这些布局涉及到移位。如果您现在设置一个布局的可见性为消失,另一个将占用空间,因为正在消失的一个正在释放它。会有一个默认的动画,这是某种“淡出”,但我认为你可以改变这个-但最后一个我还没有测试,目前。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Android