Simultaneously scale and translate ImageView based on Target - android

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.

Related

Performing a view animation after adding the view

So my problem is that i want after double click on item in RecyclerView adapter to trigger the animation on ImageView. I detect the double tap in adapter, take the coordinates of the tapped area in format of int[] location, call the method in Fragment passing the location.
public void performAnimation(int[] location) {
ImageView imageView = new ImageView(getContext());
imageView.setImageDrawable(getActivity().getDrawable(R.drawable.ic_imageview));
ConstraintLayout.LayoutParams params =
new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0, location[0], 0, location[1]);
imageView.setLayoutParams(params);
parentViewGroup2.addView(imageView);
ObjectAnimator translateAnim = ObjectAnimator.ofFloat(imageView, View.TRANSLATION_Y, 0.5f);
translateAnim.setDuration(2000);
translateAnim.start();
So the problem is that i only get to draw the image in layout, but animation wont start. I have also tryed that with TransitionManager with beginDelayedTransition, but again, nothing. Does anyone have any idea what am i doing wrong? Thanks in advance.
ObjectAnimator.ofFloat receives an array of float values of which value the animation will run through, you only pass 1 0.5f param which is not enough. Also, the float here should be an absolute pixel on the screen will be translated, not an offset value.
Try this ViewPropertyAnimator instead:
imageView.animate().translationY(400).setDuration(200).start();

How to move a rotated view in the right direction on Android?

I have a View I rotate programmatically by a random degree with
view.setRotation(rnd.nextInt(181));
How can I now move the view in the direction of the rotation? If I use
view.animate().translationXBy...
the view will move to the left or right. Is there a way to combine translationX and translationY to have the view move exactly in the direction of the rotation? Or any other way to achieve this?
Ok, I found the solution myself with Pythagoras:
float rotation = view.getRotation();
float translationX = (float)(Math.cos(Math.toRadians(rotation)) * distance);
float translationY = (float)(Math.sin(Math.toRadians(rotation)) * distance);
view.animate().translationXBy(translationX).translationYBy(translationY)
Use tween animation set of rotate and translate animation by method of view setAnimation()
for example:
RotateAnimation animation=new RotateAnimation(0, 360);
animation.setRepeatCount(-1);
animation.setRepeatMode(Animation.RESTART);
textView.setAnimation(animation);
animation.start();

Start simple Animation top to bottom from a specific position

I need to make a textview that perform an animation from top to bottom and the animation start with the y value 50. How to do it? Thanks in advance.
You can use TranslateAnimation.
TranslateAnimation uses deltas, so to calculate the position of 50px from the top of the screen, subtract the top of the view & add 50.
In this example, I set the toY by adding some value to the fromY.
Here's the code:
int fromY = 50 - view.getTop();
int toY = fromY + someValue;
TranslateAnimation animation = new TranslateAnimation(0, 0, fromY, toY);
animation.setDuration(someDuration);
view.startAnimation(animation);
Hope this helps :)

how to move a button to left or right programmatically in android

I want to animate a button by getting its co-ordinates and then increasing or decreasing them one by one so that the button can go to left and then come to the right.
Use a TranslateAnimation:
TranslateAnimation animation = new TranslateAnimation(start_x, start_y, end_x, end_y);
animation.setDuration(1000); // duartion in ms
animation.setFillAfter(false);
button.startAnimation(animation);
I'm not sure how you can get it's position, button.getTop() and button.getLeft() could work...
Not sure if this will help you but i was struck with the same problem i was able to do this using these methods, setTranslationX(float) setTranslationY(float)
you can use it Like this
Button button = (button) findViewById(your id);
button.setTranslationX(a float value);
here's the android documentation that provide more information http://developer.android.com/reference/android/view/View.html#attr_android:translationX
Solution for those who are looking for left to right animation)
TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 1500.0f); // new TranslateAnimation (float fromXDelta,float toXDelta, float fromYDelta, float toYDelta)
animation.setDuration(1500); // animation duration
animation.setRepeatCount(1); // animation repeat count
animation.setFillAfter(false);
your_view .startAnimation(animation);//your_view for mine is imageView
Solution for those who are looking for repeated animation(for eg. left to right and right to left)
TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 1500.0f); // new TranslateAnimation (float fromXDelta,float toXDelta, float fromYDelta, float toYDelta)
animation.setDuration(1500); // animation duration
animation.setRepeatCount(4); // animation repeat count
animation.setRepeatMode(2); // repeat animation (left to right, right to left)
animation.setFillAfter(true);
your_view .startAnimation(animation);//your_view for mine is imageView
When button clicked image moves from left to right
you can use this code for fragments also.
insert this code in onCreateView for fragments or directly use button listener.
View view = inflater.inflate(R.layout.fragment_move,container,false);
mBtnMove = view.findViewById(R.id.btn_move);
mImageMove = view.findViewById(R.id.imv_move);
mBtnMove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
float start_x_axis = 0; // initialize the axis value start from and end
float start_y_axis = 1000;
float end_x_axis = 0;
float end_y_axis = 0;
TranslateAnimation animation = new TranslateAnimation(start_x_axis, start_y_axis, end_x_axis, end_y_axis);
animation.setDuration(2500); // Duration of image to move from left to right
mImageMove.startAnimation(animation);
}
});
return view;

Android ScaleAnimation and TranslateAnimation, how to avoid ScaleAnimation movement

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~

Categories

Resources