As the title suggests, I would like to know programmatically if a given View has been rotated already. Here is my animation function:
public static void AnimateArrowDown(View v)
{
RotateAnimation anim = new RotateAnimation(0.0f, 90.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(200);
anim.setFillAfter(true);
v.findViewById(R.id.arrow_imageview).startAnimation(anim);
}
I'm animating an arrow right to down inside a ListView. My problem is when the view is redraw for some list elements the arrow previously rotated for another list item gets passed to this new list item. Hence, I would like to determine if the arrow in the ListView has been rotated and if so then rotate the arrow to its actual position.
You can use View.getRotation method.
float rotation = v.findViewById(R.id.arrow_imageview).getRotation();
Then you can determine the value is default (0.0f; not rotated) or not (90.0f; rotated).
(Note: However, I would also prefer another approach using state flags like Saehun Sean Oh mentions in his comment. I don't think they need to be static but to be field members, and keep boolean states there.)
Related
I am making a Rollette game and I want to play sound in each crossing section like if 1 is crossing it should find some trigger or collision detection and ping one tick sound. My problem is that I am not able to find the collision detection on image. Below is the approaches that I have done.
I have taken LayoutView and placed a Rollette wheel image inside it.
In each section (0-9) has taken a green small button which will be used to detect the collision with the arrow. Once it collides there will be a Tick sound with up-down animation in arrow. (Image attached).
Problem.
I am not able to find the new co-ordinate of views in each rotation. It is returning the same static location every time and hence collision is never happening.
Rotation Code..
final RotateAnimation rotate = new RotateAnimation(0, 360f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(10000);
rotate.setFillAfter(true);
Collision detection code...
Rect arrowBtnRect = new Rect();
arrowBtn.getGlobalVisibleRect(arrowBtnRect);
Rect btn0Rect = new Rect();
btn0.getGlobalVisibleRect(btn0Rect);
if(arrowBtnRect.intersect(btn0Rect)) {
System.out.println("Collision detected "+numberSelected);
numberSelected = "0";
return true;
}
Your idea is brilliant!
But I have certain remarks on your approach:
setFillAfter() is not helping, according to documentations:
If fillAfter is true, the transformation that this animation performed will persist when it is finished.
I recommend using ObjectAnimator instead of RotateAnimation. While RotateAnimation is just making the view looks as if it is rotating until you call fillAfter (which happens after animation stops), ObjectAnimator makes the view really change its actual angle while rotating. See this: https://stackoverflow.com/a/29465710/10005752
Usage:
Random random = new Random();
float randomAngle = (float) (random.nextInt(360) + 1);
ObjectAnimator rouletteAnimator = ObjectAnimator.ofFloat(rouletteView, View.ROTATION, 0f, randomAngle);
rouletteAnimator.setDuration(10000);
rouletteAnimator.start();
Also, to elaborate more on my comment I recommend that get all angles that have buttons on them before starting animating, and when animation starts keep using rouletteView.getRotation(); to check what angle is at the top.
Example:
Button1 is at angle 90 and rouletteView is rotating Counter Clockwise. Then if rouletteView.getRotation() == 360 - 90 is true then Button1 is touching the arrow.
I hope I'm clear!
simple question I cant find the answer anywhere, is there a way to rotate a spinner, without rotating screen or anything just create a spinner which is rotated 90 degrees?
Thanks in advance.
On API Level 11+, you are welcome to rotate any View via android:rotation in your layout XML or setRotation() in Java. Whether this will give you something that your users will like, I cannot say.
Programmatically you can try something like this -
RotateAnimation animation = new RotateAnimation(fromDegrees, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
// Adding the time needed to rotate the image
animation.setDuration(250);
// Set the animation to stop after reaching the desired position. Without this it would return to the original state.
animation.setFillAfter(true);
//Then set the animation to your view
view.startAnimation(animation);
working in android last couple of days and i am trying to rotate an arrow by pressing a button. Using RotateAnimation and:
setFillAfter(true);
arrow remains in last position as supposed to.
But when i press button again arrow yes starts to rotate from initial position, but there is also the "previous" arrow from the last call of animation which is finally overlapped by "new" arrow. So i guess i need to somehow reset/clear the setFillAfter but i can't find a way.
My code goes like this:
//Animation start
float Xaxis=0.835366f;
float Yaxis=0.676692f;
RotateAnimation rotateAnimation1 = new RotateAnimation(0, 180,
Animation.RELATIVE_TO_SELF, Xaxis,Animation.RELATIVE_TO_SELF, Yaxis);
rotateAnimation1.setInterpolator(new LinearInterpolator());
rotateAnimation1.setDuration(2500);
rotateAnimation1.setRepeatCount(0);
image.startAnimation(rotateAnimation1);
rotateAnimation1.setAnimationListener(this);
#Override
public void onAnimationEnd(Animation animation) {
animation.setFillAfter(true);
}
Any ideas would be usefull..
I have tried invalidate, clearAnimation to image, setting fillafter to false, reset on animation but still same.
It is fixed, emulator is configured with shared GPU and runs perfectly. Fast and without any remainings of previous animations.
Alphaing a drawable work well like this:
if(mAlphaAnimation == null){
mAlphaAnimation = ObjectAnimator.ofFloat(this, "alpha", 0.0f,1.0f).setDuration(TARGET_ANIM_ALPHA_DURATION);
mAlphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
mAlphaAnimation.setStartDelay(TARGET_ANIM_ALPHA_DELAY_BASE*power);
mAlphaAnimation.setRepeatCount(ValueAnimator.INFINITE);
mAlphaAnimation.setRepeatMode(ValueAnimator.REVERSE);
mAlphaAnimation.addUpdateListener(this);
}
But if I want rotate a drawable like below , it don's work.
private void createRotateAnim(float fromDegress,float toDegress,int duration){
if(mRotateAnimation == null){
mRotateAnimation = ObjectAnimator.ofFloat(this, "rotation",fromDegress,toDegress).setDuration(duration);
mRotateAnimation.setStartDelay(100);
mRotateAnimation.setInterpolator(new AccelerateInterpolator());
mRotateAnimation.addUpdateListener(this);
}
}
Anyone can help me to fix this issue, or these is any other way to create a rotation drawable animation .
I am sorry to my poor English.
Try with ObjectAnimator instead.
ImageView imageview = (ImageView)findViewById(R.id.image);
ObjectAnimator imageViewObjectAnimator = ObjectAnimator.ofFloat(imageview ,
"rotation", 0f, 360f);
imageViewObjectAnimator.setDuration(1000); // miliseconds
imageViewObjectAnimator.start();
EDIT
Since this question draw some attention let me to explain why to use ObjectAnimator instead of other Transition animators
The thing about using ObjectAnimator is that it's moving both the visible and the clickable area of the item, if you use another animation method, for example Transition Animation or some other Animators, and let's say if you want to move the Button from the bottom left of the screen to the top left, it will only move the visible area but not the Button itself, the clickable area will still be on the previous position, in this case the clickable area will still be on the bottom left instead of the top left where you moved the button.
If you do the same with ObjectAnimator, both the visible area, and the clickable area will move the the desired location.
Try this simple Rotation Animation applied to a image.
ImageView imageview = (ImageView)findViewById(R.id.myimage);
RotateAnimation rotate = new RotateAnimation(180, 360, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(500);
imageview.startAnimation(rotate);
This answer is just for a sake of question, it is correct that Clickable area will be different than View's current position. Please check this question for making clickable area correct. Button is not clickable after TranslateAnimation
In my application, I am rotating a clock hand to the desired amount of minutes. This works good with RotateAnimation. Now what I want to do is to return the hand back to the starting position (0 minutes).
For example:
I first rotate the hand like this:
final RotateAnimation anim = new RotateAnimation(0f, ammountDegress, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 1f);
anim.setFillAfter(true);
anim.setFillEnabled(true)
Then I would like to move the hand back to it's starting position, so that means I should be calling a RotateAnimation after the first animation ends.
The problem is that the pivots have changed, how I can I set the pivot position to the exact position as previous? So that the rotating point is again at the same position of the clock hand.
Edit To make it more clearer - I would like to have something like a fixed point pivot that doesn't change with the rotation, so I am always rotating the hand around the same point.
I hope you can understand what I mean.