I am changing the left margin of an image view in the following manner :
ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) image.getLayoutParams ();
layoutParams.leftMargin = VALUE;
image.setLayoutParams ( layoutParams );
I would like the change in margin to apply with animation. Any clues ?
What I tried :
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat ( image , "x" , VALUE);
objectAnimator.start();
This works perfectly, as the image is moved to the specified X value with animation, HOWEVER the value of layoutParams.leftMargin remains unchanged !! So I cannot use this method, because if I try to change the value of layoutParams.leftMargin to 100 after using the objectAnimator with the value 100, the value applied is not correct ( 200 is applied instead of 100, the effect if the objectAnimator remains eventhough I am setting the left margin in the following manner :
layoutParams.leftMargin = 100;
Use Animation class, not 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);
Please note that you should use correct LayoutParams class i.e. if your view is the child of LinearLayout then params should be LinearLayout.LayoutParams
I came by this question, but I couldn't use it because I want to animate the margin from a negative value to 0, so I used valueAnimater base on user1991679 answer:
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();
You must change LinearLayout.LayoutParams according to animatedView container.
Also you can use nineoldandroids for older version that don't have ValueAnimator.
The answer from user1991679 is great, but if you need to interpolate a margin from any other value but 0, you need to use it in your calculations:
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);
In my case I needed to animate an "enter the screen" animation, coming from "-48dp" to 0. Without the start value, the animation is always 0, thus jumping, not animating the view. The solution was to interpolate the offset and add it to the original value.
You can use the following
image.animate().setDuration(durationIn).translationXBy(offsetFloat).start();
You can also add .setInterpolator(new BounceInterpolator())
to change the look of the animation.