【问题标题】:Android - Change left margin using animationAndroid - 使用动画更改左边距
【发布时间】:2012-12-02 14:47:25
【问题描述】:

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

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;

【问题讨论】:

标签: android android-animation


【解决方案1】:

使用 Animation 类,而不是 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

【讨论】:

  • 别忘了设置持续时间,在我设置持续时间之前我遇到了一些问题:a.setDuration(duration);
  • 尝试使用 params.leftMargin 时出现错误。显然它不是一个字段
  • 这是因为有很多 LayoutParams 类。例如 - ViewGroup.LayoutParams、FrameLayout.LayoutParams、LinearLayout.LayoutParams 等。ViewGroup.LayoutParams 没有 leftMargin 字段,但 RelativeLayout.LayoutParams 有。
  • 根据developer.android.com/reference/android/view/animation/…,默认时长是0ms,所以你也要设置时长。
  • 如果我希望 newLeftMargin 为 0 怎么办?
【解决方案2】:

我是通过这个问题来的,但我无法使用它,因为我想将边距从负值设置为 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 的旧版本。

【讨论】:

  • 您可以使用 Animation 类将边距从负数设置为 0。没有任何限制。
  • @user1991679 以及如何使用 Animation 类从 400 到 200 进行动画处理?
  • 假设 200 是 newMargin (我们应该动画的边距), 400 是 currentMargin (我们动画的边距)。在这种情况下,代码将如下所示: @Override protected void applyTransformation(float interpolatedTime, Transformation t) { LayoutParams params = yourView.getLayoutParams(); params.leftMargin = currentMargin - (int)((currentMargin - newMargin) * interpolatedTime); yourView.setLayoutParams(params); }
  • 我得到了奇怪的重绘。看起来我的布局很不稳定。
  • @MikeMilla 在 FrameLayout 中使用它,LinearLayout 会产生不好的效果。
【解决方案3】:

你可以使用以下

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

你也可以添加.setInterpolator(new BounceInterpolator())来改变动画的外观。

【讨论】:

    【解决方案4】:

    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,因此是跳跃,而不是动画视图。解决方案是插入偏移量并将其添加到原始值。

    【讨论】:

    • 我试过这个。虽然结果是正确的位置,但它不再做动画了。任何想法?如果我回到非计算的东西,动画效果很好..
    • 你可以在设置好开始点之后直接设置断点,这样你就可以看到输入了什么。如果它跳跃,则意味着您分配了错误的值。在我的代码 sn-p 中,bottomMarginStart 是从视图中读取的,假设视图应该从它所在的位置开始动画。
    【解决方案5】:

    没有什么像我想要的那样对我有用... 我需要创建从 -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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-09
      • 2017-12-20
      • 2011-12-15
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 2016-11-22
      • 2017-11-21
      相关资源
      最近更新 更多