1

I currently have a button that when clicked an animation begins that shows a LinearLayout above the button. The LinearLayout is directly above it. In the xml file the LinearLayouts visibility is set to GONE. So when the button is clicked the visibility is set to VISIBLE. Then the animation begins. The animation is a slidedown animation. Everything works perfectly. But When the button is clicked the button jumps to the bottom of where the LinearLayout ends. Even though the LinearLayout is still going through the animation. How can I make the button move with the LinearLayout animation? I want everything to be a smooth transition. But the button jumps and it doesn't look very smooth.

LInearLayout Animation

<?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>
4

2 回答 2

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。如果您愿意,可以选择固定的持续时间。

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

于 2013-10-23T14:02:47.007 回答
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()));
    }
于 2016-05-25T07:38:48.903 回答