im trying to rotate an imageview in certain degrees and at the same time expand this imageview's height !
my code so far is :
public class TongueHandler {
ImageView tongue;
RelativeLayout.LayoutParams tongue_params;
ObjectAnimator rotate_tongue;
ScaleAnimation scale_tongue;
AnimationSet as;
ImageView frog;
Button btn;
public TongueHandler(Button btn,ImageView frog,ImageView tongue){
this.btn=btn;
this.frog=frog;
this.tongue=tongue;
}
public void Initialize()
{
tongue.setBackgroundColor(Color.RED);
tongue_params=new RelativeLayout.LayoutParams(10,100);
tongue_params.leftMargin=frog.getLeft()+frog.getWidth()/2;
tongue_params.topMargin=frog.getTop()+frog.getHeight()/2;
tongue.setLayoutParams(tongue_params);
Animate();
}
public void Animate()
{
as=new AnimationSet(true);
rotate_tongue=ObjectAnimator.ofFloat(tongue, "rotationX", 90.0f, 90+CalcAngle(frog,btn));
rotate_tongue.setDuration(1);
rotate_tongue.start();
System.out.println("This is Angle: "+CalcAngle(frog,btn));
/* scale_tongue=new ScaleAnimation(1,1,30,btn.getY(),1,2);
scale_tongue.setDuration(500); */
// as.addAnimation(scale_tongue);
tongue.startAnimation(as);
as.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
/* as=new AnimationSet(false);
rotate_tongue=new RotateAnimation(0,CalcAngle(frog,btn),frog.getWidth()/2,frog.getHeight()/2);
rotate_tongue.setDuration(1);
scale_tongue=new ScaleAnimation(30,btn.getY(),2,2,15,0);
scale_tongue.setDuration(200);
as.addAnimation(rotate_tongue);
as.addAnimation(scale_tongue);
tongue.startAnimation(as);*/
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
public float CalcAngle(View frog,View fly)
{
float angle = (float) Math.toDegrees(Math.atan2(frog.getY() - DataBase.FlyY, frog.getX() - DataBase.FlyX));
if(angle < 0){
angle += 360;
}
/* if (frog.getX()>=DataBase.FlyX)
{
angle=-90f-angle;
}
else
{
angle=-90f+angle;
}*/
return angle;
}
}
the problem is that doesnt work at all as the image rotates but in wrong degrees (also i would like to do this instantly not even with 1ms delay) and generally the result is not sutisfying
any help is really appreciated
thank you ;)
Related
I have a question of RotationAnimation.
First.
Is there a Listener to during animation?
start, start animation
repeat, repeat animation
stop, stop animation.
but there are no animation listener to check the on going.
second,
is any other get a current rotate angle of image?
I think, ImageView is rotate by rotationAnimation function.
so I made a timer thread and run 1second
'''
timer = new Timer();
timerTask = new TimerTask() {
public void run(){
Log.e("LOG", " [angle]: " + String.format("%3.1f", rotateImage.getRotation());
}
};
timer.schedule(timerTask, 0, 1000);
'''
but, I can't see the changed value during rotate.
how can I get the current angle during rotate?
thanks.
For Rotation Animation, Yes There is as shown below:
RotateAnimation rotateAnimation = new RotateAnimation();
rotateAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
You can also use Object Animators to animate Rotation:
ObjectAnimator rotateAnimation = ObjectAnimator.ofFloat(targetView, View.ROTATION, startAngle, endAngle);
rotateAnimation.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
To get the angle of your ImageView simply use imageView.getRotation(); this will give you an int value of the current angle of rotation.
You also don't need Timer because both ObjectAnimator and rotateAnimator provide time control for you:
rotateAnimation.setDuration(1000); // run animation for 1000 milliseconds or 1 second
rotateAnimation.setStartDelay(1000); // delay animation for 1000 milliseconds or 1 second
Finally, To get rotation Angle DURING the time animation is running there is a listener method called addUpdateListener :
rotateAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue(); // dynamic value of angle
}
});
I have
Layout Game (Relative Layout)
ImageView (The Player)
ViewPropertyAnimator (The Animation)
My Code is:
final Vibrator vibe = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
final ImageView playerImageView = (ImageView) layoutInflater.inflate(R.layout.player, null);
playerImageView.setLayoutParams(new RelativeLayout.LayoutParams(playerSizeX, playerSizeY));
playerImageView.setImageDrawable(playerDrawable);
playerImageView.setX(playerVisualPositionX);
playerImageView.setY(playerVisualPositionY);
playerImageView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
vibe.vibrate(100);
touchedPlayer();
}
return true;
}
});
layoutGame.addView(playerImageView);
ViewPropertyAnimator viewPropertyAnimator = playerImageView.animate();
viewPropertyAnimator.x(positionAnimateX); // The view will be animated such that it moves to positionAnimateX.
viewPropertyAnimator.y(positionAnimateY); // The view will be animated such that it moves to positionAnimateY.
viewPropertyAnimator.setDuration(animationTime);
viewPropertyAnimator.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
//super.onAnimationEnd(animation);
layoutGame.removeView(playerImageView);
if (!gameOver && !gamePaused) {
addNewPlayer();
}
}
#Override
public void onAnimationStart(Animator animation) {
//super.onAnimationStart(animation);
currentAnimation = animation;
}
});
Sometimes I touch on the Player but onClicListener on ImageView is not called/fired method touchedPlayer() during animation. Do you know what it can be?
Try using an ObjectAnimator instead to animate X and Y for your view, I never experienced such problems and I use it a lot for stuff similar to what you're doing here.
Try this and see if it works:
layoutGame.addView(playerImageView);
PropertyValuesHolder xHolder = PropertyValuesHolder.ofFloat("X", playerImageView.getX(), positionAnimateX); // The view will be animated such that it moves to positionAnimateX.
PropertyValuesHolder yHolder = PropertyValuesHolder.ofFloat("Y", playerImageView.getY(), positionAnimateY); // The view will be animated such that it moves to positionAnimateY.
ValueAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(playerImageView, xHolder, yHolder);
valueAnimator.setDuration(animationTime);
valueAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
//super.onAnimationStart(animation);
currentAnimation = animation;
}
#Override
public void onAnimationEnd(Animator animation) {
//super.onAnimationEnd(animation);
layoutGame.removeView(playerImageView);
if (!gameOver && !gamePaused) {
addNewPlayer();
}
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
valueAnimator.start();
I would like to rotate an imageView 10 times, every times, the imageView will load randomly an image in drawable resources. For example: there are 6 images like img1 to img6. I did the code like this, but it doesn't work
public void clockwise(View view){
for (int i=1; i<=6; i++){
ImageView image = (ImageView)findViewById(R.id.imageView);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
animation.setRepeatCount(10);
int max=6, min=1;
int randNum = min + (int)(Math.random()*((max-min)+1));//
if (randNum==1) image.setImageDrawable(getResources().getDrawable(R.drawable.die1));
else if (randNum==2) image.setImageDrawable(getResources().getDrawable(R.drawable.die2));
else if (randNum==3) image.setImageDrawable(getResources().getDrawable(R.drawable.die3));
else if (randNum==4) image.setImageDrawable(getResources().getDrawable(R.drawable.die4));
else if (randNum==5) image.setImageDrawable(getResources().getDrawable(R.drawable.die5));
else if (randNum==6) image.setImageDrawable(getResources().getDrawable(R.drawable.die6));
image.startAnimation(animation);
}
It just load only one image that I set in xml file for 10 times of repeating
you can use animation listener like below
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});)
So in onAnimationRepeat method you can change your image.
instead of loop use Animation Listener.
ImageView image = (ImageView)findViewById(R.id.imageView);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
animation.setRepeatCount(10);
image.startAnimation(animation);
Overrided methods.
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
int max=6, min=1;
int randNum = min + (int)(Math.random()*((max-min)+1));//
if (randNum==1) image.setImageDrawable(getResources().getDrawable(R.drawable.die1));
else if (randNum==2) image.setImageDrawable(getResources().getDrawable(R.drawable.die2));
else if (randNum==3) image.setImageDrawable(getResources().getDrawable(R.drawable.die3));
else if (randNum==4) image.setImageDrawable(getResources().getDrawable(R.drawable.die4));
else if (randNum==5) image.setImageDrawable(getResources().getDrawable(R.drawable.die5));
else if (randNum==6) image.setImageDrawable(getResources().getDrawable(R.drawable.die6));
}
Thanks KDeogharkar and Ragesh for your suggestion.
I've tried to used your way that is changing image onAnimationRepeat(), but it still doesn't work. I guess that is caused because the image is still being used by the animation, so it doesn't allow to change the image. Therefore, I write a recursive function that waits for the end of the animation to change image, and call the same animation, so finally it works. Here is my code
public void rotate(int count){
//
final int nextCount = count - 1;
ImageView image = (ImageView)findViewById(R.id.imageView);
int max = 6, min = 1;
int randNum = min + (int) (Math.random() * ((max - min) + 1));//
if (randNum == 1)
image.setImageDrawable(getResources().getDrawable(R.drawable.die1));
else if (randNum == 2)
image.setImageDrawable(getResources().getDrawable(R.drawable.die2));
else if (randNum == 3)
image.setImageDrawable(getResources().getDrawable(R.drawable.die3));
else if (randNum == 4)
image.setImageDrawable(getResources().getDrawable(R.drawable.die4));
else if (randNum == 5)
image.setImageDrawable(getResources().getDrawable(R.drawable.die5));
else if (randNum == 6)
image.setImageDrawable(getResources().getDrawable(R.drawable.die6));
Animation animation;
animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
animation.setRepeatCount(1);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (nextCount >=0) rotate(nextCount);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
image.startAnimation(animation);
}
After that, I just need to call rotate(animationTimes) in main() function.
I can't get the circular reveal animation to work.
I think I checked the most obvious things:
It starts, width and height are > 0 and it is visible, no Exception..
I load some data from the internet and display it in the view(fab)
The animation should only play after the download finishes.
TmdbHelper helper = new TmdbHelper();
helper.getMovieById(id, "en", new TmdbHelper.ResultListener() {
#Override
public void onResultReceived(JSONObject result) {
// called when finished downloading
try {
String rating = result.getString("vote_average");
AnimationHelper.circularReveal(fab, 500, 0);
fab.setText(rating);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
AnimationHelper:
public static void circularReveal(final View view, final long duration, long startDelay) {
// get the center for the clipping circle
int cx = (view.getLeft() + view.getRight()) / 2;
int cy = (view.getTop() + view.getBottom()) / 2;
// get the final radius for the clipping circle
int finalRadius = Math.max(view.getWidth(), view.getHeight());
// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(view, cx, cy, 0, finalRadius);
anim.setDuration(duration);
anim.setStartDelay(startDelay);
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
view.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {}
});
// make the view visible and start the animation
anim.start();
}
I use the circular reveal animation in other parts like this to make sure the view is attached, and it works:
headerContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
headerContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
AnimationHelper.circularReveal(headerContainer, 500, 200);
}
});
Perhaps you should erase this line inside your onResultRecieved():
fab.setVisibility(View.VISIBLE);
My assumption is that your circular reveal method is working just fine. It is because of you have made the FAB visible before the animation even begin, you can't see it in action.
As an addition, those lines you've shown which is working doesn't have fab.setVisibility(View.VISIBLE) called anywhere in it.
1st Approach:
Try Transition Listener.
getWindow().getSharedElementExitTransition().addListener(new Transition.TransitionListener() {
#Override
public void onTransitionStart(Transition transition) {
}
#Override
public void onTransitionEnd(Transition transition) {
}
#Override
public void onTransitionCancel(Transition transition) {
}
#Override
public void onTransitionPause(Transition transition) {
}
#Override
public void onTransitionResume(Transition transition) {
}
});
2nd Approach: Try setting start delay and listener to the reveal animation and when animation starts then set the view visible
if (Build.VERSION.SDK_INT >= 21) {
Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);
anim.setStartDelay(300);
anim.setDuration(1000);
anim.setInterpolator(new DecelerateInterpolator());
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
viewRoot.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
anim.start();
}
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
anim.start();
I have several ImageViews in a RelativeLayout.
When the user taps any of the ImageViews, I want the ImageView to be moved to a specified location using a subtle animation.
Eg; I have initially set margins for LayoutParams associated with an ImageView as layoutparams1.setMargins(90,70,0,0); and I have then added it to the layout.
When the ImageView is tapped, I'd like its new location to be 200,200, done with animation.
So, is it possible? if yes, then how?
Note that I have both RelativeLayout and all of its child ImageViews created programmatically.
And I'm new to Android development so an elaborative answer is expected.
TranslateAnimation animation = new TranslateAnimation(0, 50, 0, 100);
animation.setDuration(1000);
animation.setFillAfter(false);
animation.setAnimationListener(new MyAnimationListener());
imageView.startAnimation(animation);
UPDATE :
The problem is that the View is actually still in it's old position. So we have to move it when the animation is finished. To detect when the animation is finished we have to create our own animationListener (inside our activity class):
private class MyAnimationListener implements AnimationListener{
#Override
public void onAnimationEnd(Animation animation) {
imageView.clearAnimation();
LayoutParams lp = new LayoutParams(imageView.getWidth(), imageView.getHeight());
lp.setMargins(50, 100, 0, 0);
imageView.setLayoutParams(lp);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
}
So the onClickEvent will get fired again at it's new place.
The animation will now move it even more down, so you might want to save the x and y in a variable, so that in the onAnimationEnd() you move it not to a fix location.
It is better to use ObjectAnimator which actually moves the ImageView to the new position.
E.g.:
ImageView splash;
#Override
public boolean onTouchEvent(MotionEvent event) {
float tx = event.getX();
float ty = event.getY();
int action = event.getAction();
switch(action) {
case MotionEvent.ACTION_DOWN:
tx = event.getX();
ty = event.getY();
// findViewById(R.id.character).setX(tx-45);
// findViewById(R.id.character).setY(ty-134);
ObjectAnimator animX = ObjectAnimator.ofFloat(splash, "x", tx-45);
ObjectAnimator animY = ObjectAnimator.ofFloat(splash, "y", ty-134);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();
break;
default:
}
return true;
}
you can use this code
imageView.animate().x(80).y(212).setDuration(300);
or
for soft animation you can use this library
https://github.com/wirecube/android_additive_animations
In below code I am adding a image view in center on frame layout dynamically. After add I am increase scaling and set alpha to give zoom effect and after complete animation I am just translate my image view one position to another position.
Add image view on framelayout
imgHeart = new ImageView(getBaseContext());
imgHeart.setId(R.id.heartImage);
imgHeart.setImageResource(R.drawable.material_heart_fill_icon);
imgHeart.setLayoutParams(new FrameLayout.LayoutParams(50, 50, Gravity.CENTER));
mainFrameLaout.addView(imgHeart);
Add animation on image view
imgHeart.animate()
.scaleXBy(6)
.scaleYBy(6)
.setDuration(700)
.alpha(2)
.setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
imgHeart.animate()
.scaleXBy(-6f).scaleYBy(-6f)
.alpha(.1f)
.translationX((heigthAndWidth[0] / 2) - minusWidth)
.translationY(-((heigthAndWidth[1] / 2) - minusHeight))
.setDuration(1000)
.setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
// remove image view from framlayout
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}).start();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}).start();
you can use this code :)
private void animeView(View imageView){
Handler handler = new Handler();
final int[] deltaX = {50};
final int[] deltaRotation = {45};
handler.postDelayed(new Runnable() {
#Override
public void run() {
imageView.animate().translationX(deltaX[0])
.rotation(deltaRotation[0]).setDuration(1000) ;
deltaX[0] *=-1 ;
deltaRotation[0] *=-1 ;
handler.postDelayed(this , 1000);
}
},1000);
}