I have an AnimationSet with inside a ScaleAnimation and a TranslateAnimation like this:
TranslateAnimation:
TranslateAnimation goTopFromRight =
new TranslateAnimation(0, -(right.getLeft()-top.getLeft()),
0,-(right.getTop()-top.getTop()));
ScaleAnimation:
ScaleAnimation = setSizeForTop = new ScaleAnimation(1, 2, 1, 2);
and AnimationSet:
bringToLeftFromTopAnimationSet = new AnimationSet(true);
bringToTopFromRightAnimationSet.addAnimation(goTopFromRight);
bringToTopFromRightAnimationSet.addAnimation(setSizeForTop);
The problem is that when i try to use only the ScaleAnimation, my item goes to the position i want, but whe I am using the ScaleAnimation with the TranslateAnimation in the AnimationSet, my item translates more than i need, as if ScaleAnimation introduces some supplementary movements abd I don't know how to delete them.
Thank you for your help.
The correct solution is to change order of animations. Scale must go first:
bringToTopFromRightAnimationSet.addAnimation(setSizeForTop);
bringToTopFromRightAnimationSet.addAnimation(goTopFromRight);
To avoid the ScaleAnimation movement when using the ScaleAnimation and TranslateAnimation, you have to multiply the TranslateAnimation parametres with those from ScaleAnimation like this:
TranslateAnimation goRightFromTop;
ScaleAnimation sizeNotUp;
goRightFromTop = new TranslateAnimation(0,(-( invisibleCenterImageView.getLeft() - imageViewRight.getLeft() ))*(1/0.6667f), 0, (-( invisibleCenterImageView.getTop() - imageViewRight.getTop()))*(1/0.6667f));
sizeNotUp = new ScaleAnimation(1,0.6667f,1,0.6667f,Animation.RELATIVE_TO_SELF, (float)0.5, Animation.RELATIVE_TO_SELF, (float)0.5);
And then, surprise you deleted the ScaleAnimation movement.
I remember having weird problems with nested animations as well.
Have you tried setting the pivot point manually? See public ScaleAnimation (float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) from http://developer.android.com/reference/android/view/animation/ScaleAnimation.html for it.
It could work.
My solution is to add a container outside your view, and apply the scale animation to your view while applying translate animation to the container.
Then you can make more complex animation even via XML~
Related
Whenever I use TranslateAnimation to move an object to a new location, for some reason, the touch target of that object remains in the old position.
How do I change this behaviour?
eg.
public static void hideViewUp (View v, int duration) {
AnimationSet animSet = new AnimationSet(true);
animSet.setFillAfter(true);
animSet.setDuration(duration);
AlphaAnimation alp = new AlphaAnimation(1.0f, 0);
TranslateAnimation translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
Animation.RELATIVE_TO_SELF,
Animation.RELATIVE_TO_SELF,
-(v.getTop() + v.getHeight()));
animSet.addAnimation(translate);
animSet.addAnimation(alp);
v.startAnimation(animSet);
}
There's no need to post any sample code - the issue is indeed pretty well known and general.
TranslateAnimation and all other old types of animation change only the draw transformation matrix. These animations shouldn't be used to move items permamently.
To truly move a view to a new position, use ObjectAnimator.
Here's an example: http://www.android-app-market.com/animations-in-android-translate-animation-alpha-animation-object-animation.html
use Tween Animation code:
#Override
public void onClick(View v) {
RotateAnimation rotateAnimation = new RotateAnimation (0,90,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0);
rotateAnimation.setDuration (2000);
rotateAnimation.setFillAfter (true);
image2.startAnimation (rotateAnimation);
}
of cause use Tween Animation can do that,but Tween Animation hava a defect.
For example the following gif click event does not move.
So I want use property Animation to do that,but I found property Animation can only rotate around the Center.
how can i use property Animation to rotate view around the point?
I think from your question that you want rotation around the mouse pointer.
Try this, I think it should work but I haven't had a chance to try it yet.
...
Animation rotateAnimation = new RotateAnimation(0.0f, 360.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.0f);
...
What I want to do is simultaneously scale and translate an ImageView based when the user touches is. The final position and size of the ImageView should be equal to the target.
Below is a snipper of the OnClickListener attached to every ImageView that should perform this action. The new position and size is obtained from ivYou, which also is an ImageView.
#Override
public void onClick(View v) {
// Create animations
int[] from = new int[2];
int[] to = new int[2];
//v.getLocationInWindow(from);
v.getLocationOnScreen(from);
//ivYou.getLocationInWindow(to);
ivYou.getLocationOnScreen(to);
TranslateAnimation transAnim = new TranslateAnimation(0, to[0] - from[0], 0, to[1] - from[0]);
float factorX = ivYou.getWidth() / v.getWidth();
float factorY = ivYou.getHeight() / v.getHeight();
ScaleAnimation scaleAnim = new ScaleAnimation(1.0f, factorX, 1.0f, factorY);
// Create animation set
AnimationSet set = new AnimationSet(true);
set.setFillAfter(true);
set.setDuration(ANIM_DURATION);
set.addAnimation(transAnim);
set.addAnimation(scaleAnim);
// Start animations and disable click listener
v.startAnimation(set);
v.setOnClickListener(null);
}
ANIM_DURATION is 2000 miliseconds.
When I run this code the strangest things happen. The ImageView turns half a circle and gets smaller then its supposed to be. When I do not add the ScaleAnimator to the animation set, then the ImageView is moved to the new position. However, this new position isn't the same for every ImageView. Note that the ImageView's with this OnClickListener all have a different initial position.
Any help and feedback is greatly appreciated!
I was able to achieve this animation by wrapping the target View in a layout group and animating them separately.
In other words, I translate the wrapper layout, and scale the child view. Translating and scaling the same view at the same time always seems to result in unexpected animation trajectories as the scaling messes with the coordinate system the translate animation is using.
translateTarget.animate().x(deltaX).y(deltaY).setDuration(1000);
scaleTarget.animate().scaleX(0.01f).scaleY(0.01f).setDuration(1000)
Did you try this constructor?
ScaleAnimation (float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) and have pivotX be widthofimageview/2 and pivotY be the heightofimageview/2 for it to be the center. This is what I used in my translate scale animation.
I have three animations like scale, translate and scale. I play those animations in order. First two is working fine but last scale animation reset the position of view to original. If I remove last scale animation, it's working fine the view stay the new position after translate animation. Do you have any idea about this behavior?
AnimationSet animationSet = new AnimationSet(false);
animationSet.setFillAfter(true);
ScaleAnimation scaleAnimation1 = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
scaleAnimation1.setDuration(500);
scaleAnimation1.setFillAfter(true);
TranslateAnimation moveAnim = new TranslateAnimation(0, -x, 0, -y);
moveAnim.setDuration(1000);
moveAnim.setStartOffset(500);
moveAnim.setFillAfter(true);
ScaleAnimation scaleAnimation2 = new ScaleAnimation(1.0f, 0.0f, 1.0f, 0.0f);
scaleAnimation2.setDuration(500);
scaleAnimation2.setStartOffset(1000);
scaleAnimation2.setFillAfter(true);
scaleAnimation2.setFillBefore(true);
animationSet.addAnimation(scaleAnimation1);
animationSet.addAnimation(moveAnim);
animationSet.addAnimation(scaleAnimation2);
scaleAnimation2.setFillAfter(true); - If fillAfter is true, the transformation that this animation performed will persist when it is finished
scaleAnimation2.setFillBefore(true);- If fillBefore is true, this animation will apply its transformation before the start time of the animation.
These two properties cannot work simultaneously, and the one which set later is effective.
So, remove scaleAnimation2.setFillBefore(true); may solve your problem.
I am creating an animation with AnimatorSet and when it ends I would like to leave the View where it was.
The code is something like this:
mLastAnimation = new AnimatorSet();
mLastAnimation.playTogether(
ObjectAnimator.ofFloat(mImageView, "scaleX", 1.5f, 1f),
ObjectAnimator.ofFloat(mImageView, "translationY", 40f, 0f));
mLastAnimation.setDuration(3000);
mLastAnimation.addListener(this);
mLastAnimation.start();
// The Activity implements the AnimatorListener interface
#Override
public void onAnimationEnd(Animator animator) {
// Undo the animation changes to the view.
}
EDIT:
I am using the new animation API so setFillAfter() will not work here.
If you are using nineoldandroids there is a function called reverse. You can set the duration to be 0 and call reverse to reverse the animation.
You have to set the properties of the View back to its original values.
For example if you translateY 40 pixels forward, you need to translateY 40 pixels backwards. This is because the actual properties of the View have changed during property animation, not just the way it is rendered.
http://developer.android.com/guide/topics/graphics/prop-animation.html#property-vs-view
While using ObjectAnimator you can simply set
android:repeatMode="reverse"
You can use this:
ObjectAnimator scaleX = ObjectAnimator.ofFloat(mImageView, "scaleX", 1.5f, 1f);
// here is the important part!
scaleX.setRepeatMode(ValueAnimator.REVERSE);
scaleX.setRepeatCount(1);
ObjectAnimator transl = ObjectAnimator.ofFloat(mImageView, "translationY", 40f, 0f));
// here is the important part!
transl.setRepeatMode(ValueAnimator.REVERSE);
transl.setRepeatCount(1);
mLastAnimation = new AnimatorSet();
mLastAnimation.playTogether(scaleX, transl);
// the rest is the same...