67

我正在以下列方式更改图像视图的左边距:

ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) image.getLayoutParams ();
layoutParams.leftMargin = VALUE;
image.setLayoutParams ( layoutParams );

我希望边距的变化适用于动画。有什么线索吗?

我尝试了什么:

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat ( image , "x" , VALUE);
objectAnimator.start();

这非常有效,因为图像通过动画移动到指定的 X 值,但是 layoutParams.leftMargin的值保持不变!所以我不能使用这个方法,因为如果我在使用值为 100 的 objectAnimator 后尝试将 layoutParams.leftMargin 的值更改为100应用的值不正确(应用 200 而不是 100,如果objectAnimator保持不变的效果即使我以以下方式设置左边距:

layoutParams.leftMargin = 100;
4

5 回答 5

141

使用动画类,而不是 ObjectAnimator。

final int newLeftMargin = <some value>;
Animation a = new Animation() {

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        LayoutParams params = yourView.getLayoutParams();
        params.leftMargin = (int)(newLeftMargin * interpolatedTime);
        yourView.setLayoutParams(params);
    }
};
a.setDuration(500); // in ms
yourView.startAnimation(a);

请注意,您应该使用正确的 LayoutParams 类,即如果您的视图是 LinearLayout 的子视图,则参数应该是 LinearLayout.LayoutParams

于 2013-04-08T12:17:06.723 回答
96

我遇到了这个问题,但我无法使用它,因为我想将边距从负值设置为 0,所以我使用了基于 user1991679 答案的 valueAnimater:

final View animatedView = view.findViewById(R.id.animatedView);
final LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) animatedView.getLayoutParams();
ValueAnimator animator = ValueAnimator.ofInt(params.bottomMargin, 0);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator)
    {
        params.bottomMargin = (Integer) valueAnimator.getAnimatedValue();
        animatedView.requestLayout();
    }
});
animator.setDuration(300);
animator.start();

您必须根据 animatedView 容器更改 LinearLayout.LayoutParams。您也可以将 Nineoldandroids 用于没有 ValueAnimator 的旧版本。

于 2013-10-21T08:39:21.490 回答
17

user1991679 的答案很好,但是如果您需要从除 0 之外的任何其他值插入边距,则需要在计算中使用它:

ViewGroup.MarginLayoutParams params = (MarginLayoutParams) mBottomLayout.getLayoutParams();
final int bottomMarginStart = params.bottomMargin; // your start value
final int bottomMarginEnd = <your value>; // where to animate to
Animation a = new Animation() {
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        ViewGroup.MarginLayoutParams params = (MarginLayoutParams) mBottomLayout.getLayoutParams();
        // interpolate the proper value
        params.bottomMargin = bottomMarginStart + (int) ((bottomMarginEnd - bottomMarginStart) * interpolatedTime);
        mBottomLayout.setLayoutParams(params);
    }
};
a.setDuration(300);
mBottomLayout.startAnimation(a);

在我的情况下,我需要为“进入屏幕”动画设置动画,从“-48dp”到 0。没有起始值,动画始终为 0,因此跳跃,而不是动画视图。解决方案是插入偏移量并将其添加到原始值。

于 2018-02-14T13:15:59.857 回答
0

没有什么能像我想要的那样对我有用……我需要创建从 -80 dp(oldLeftMargin)到 0dp 的 ToggleMenu。与 bottomMargin 等相同。现在它可以工作了:

final int oldLeftMargin = (int) getResources().getDimension(R.dimen.left_menu_button_margin_left);
    Animation a = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) llMeniuToggle.getLayoutParams();
            params.leftMargin = oldLeftMargin + (int) ((0 - oldLeftMargin) * interpolatedTime);
            llMeniuToggle.setLayoutParams(params);
        }
    };
    a.setDuration(500);
    llMeniuToggle.startAnimation(a);
于 2021-11-23T11:47:49.237 回答
-4

您可以使用以下

image.animate().setDuration(durationIn).translationXBy(offsetFloat).start();

您还可以添加.setInterpolator(new BounceInterpolator())以更改动画的外观。

于 2017-03-07T06:34:51.120 回答