So this is my spin the bottle animation:
public static final Random RANDOM = new Random();
private int lastAngle = -1;
private ImageView bottle;
private void spinTheBottle() {
int angle = RANDOM.nextInt(3600 - 360) + 360;
float pivotX = bottle.getWidth() / 2;
float pivotY = bottle.getHeight() / 2;
final Animation animRotate = new RotateAnimation(lastAngle == -1 ? 0 : lastAngle, angle, pivotX, pivotY);
lastAngle = angle;
animRotate.setDuration(1500);
animRotate.setFillAfter(true);
bottle.startAnimation(animRotate);
}
How can I detect when the animation is done? I tried adding Animator.AnimatorListener, but that does not execute at all:
Animator.AnimatorListener listener = new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationStart", Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationEnd", Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationCancel(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationCancel", Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationRepeat(Animator animation) {
Toast.makeText(FlasketutenActivity.this, "onAnimationRepeat", Toast.LENGTH_SHORT).show();
}
};
Any tips?
It looks like you're creating the listener, but not assigning it to your animation. Try calling setAnimationListener on your animation object like this:
animRotate.setAnimationListener(new Animation.AnimationListener() {
//Listener methods
});
The first.Keep the ImageView witch and height above of zero at time
rotateAnimation.setDuration(1500);
rotateAnimation.setFillAfter(true);
rotateAnimation.setFillEnabled(true);
rotateAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.d(TAG, "onAnimationStart: ");
}
#Override
public void onAnimationEnd(Animation animation) {
Log.d(TAG, "onAnimationEnd: ");
}
#Override
public void onAnimationRepeat(Animation animation) {
Log.d(TAG, "onAnimationRepeat: ");
}
});
view.startAnimation(rotateAnimation);
it is working in my project.
But I use the animation always in xmls,it is Easy to operate and relatively by code.
Animation and Animator is not a same things.
That's all.
Assign your listener that you have created to the animation
animRotate.setAnimationListener(listener);
Related
I make some sort of quiz app and I want that every time an answer button get clicked there will be an animation changing to to yellow. after 0.25sec the next question will appear (and I want it to change back to the old color)
I already did it here:
public void onClick(View v) {
x
for (int i = 0; i < 4; i++) {
if(v == answerButtons[i]){
int j = i;
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(250);
valueAnimator.setEvaluator(new ArgbEvaluator());
valueAnimator.setIntValues(Color.WHITE,Color.YELLOW);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
answerButtons[j].setBackgroundColor((int)valueAnimator.getAnimatedValue());
}
});
valueAnimator.start();
((MainActivity)getActivity()).num++;
}
}
it does change the color but right after that the next answers(and question) support to appear on the same buttons.
I tried this:
for (int i = 0; i < 4; i++) {
if(v == answerButtons[i]){
int j = i;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
answerButtons[j].setBackgroundColor(Color.rgb(63, 81, 181));
Toast.makeText(getActivity(), "Just changed color to: button "+(j+1), Toast.LENGTH_SHORT).show();
//display(questions.get(((MainActivity)getActivity()).num));
}
},250);
}
}
x
}
but it mostly doesn't work sometimes it does. any idea why it doesn't work everytime? (the only thing it doesn't do is to change the color)
I got a solution for this one :)
apparently the postDelay function is not that precise..
int j = i;
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(250);
valueAnimator.setEvaluator(new ArgbEvaluator());
valueAnimator.setIntValues(Color.WHITE,Color.YELLOW);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
answerButtons[j].setBackgroundColor((int)valueAnimator.getAnimatedValue());
}
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
answerButtons[j].setBackgroundColor(Color.parseColor("#3F51B5"));
display(questions.get(((MainActivity)getActivity()).num));
}
});
valueAnimator.start();
I need to change button function during animation playback
#JulianoNunesSilvaOliveria said that I can change it by flag variable :
boolean something = false; if (something) { doA(); something = false;} else { doB(); }
but how i use it?
i start animation like this
oilcan.startAnimation(seq1)
You can use AnimatorListener:
oilcan.animate().setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
something = false;
}
#Override
public void onAnimationEnd(Animator animation) {
something = true;
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
}
What I want to do is simple. I want to have a looping background, so that it looks like the ground is moving. Here is how I am trying to do it however, it looks like both images are being dispatched at same time.
public void moveGround(){
startingXPosition =1500.0f;
endingXPosition = -1500.0f;
startingYPosition =0.0f;
endingYPosition =0.0f;
ImageView ground = (ImageView)findViewById(R.id.ground);
TranslateAnimation groundAnimation = new TranslateAnimation(startingXPosition,endingXPosition,startingYPosition,endingYPosition);
groundAnimation.setDuration(1500);
groundAnimation.setRepeatCount(Animation.INFINITE);
ground.startAnimation(groundAnimation);
if(ground.getLeft()<=0) {
float startingXPosition2 = 1500.0f;
float endingXPosition2 = -1500.0f;
float startingYPosition2 = 0.0f;
float endingYPosition2 = 0.0f;
ImageView ground2 = (ImageView) findViewById(R.id.ground2);
TranslateAnimation groundAnimation2 = new TranslateAnimation(startingXPosition2, endingXPosition2, startingYPosition2, endingYPosition2);
groundAnimation2.setDuration(1500);
groundAnimation2.setRepeatCount(Animation.INFINITE);
ground2.startAnimation(groundAnimation2);
}
}
try
yourAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
// do what you want
}
#Override
public void onAnimationRepeat(Animation animation) {
// do what you want
}
});
I have implemented an Android listview with flip checkboxes (GMail style) as shown here: http://techiedreams.com/gmail-like-flip-animated-multi-selection-list-view-with-action-mode/
The problem I have (even in the source code example): If there are multiple items I click/check in a fast sequence, the previous animation stops and will be restared. In other words, the previous animation does not finish and is interrupted by the second one.
Simple download the source code and try it on your own. In comparisson to gmail all animations, no matter how fast I'm clicking, are performed from the start to the end.
I can't find the piece of code in the demo source code to change this behaviour.
Any hints?
Thanks in advance :)
This is the closest I could get to Gmail's flip animation:
In the getView() method (I'm using contextual action mode):
holder.check.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mActionMode == null) {
checked = new SparseBooleanArray(alllists.size());
mActionMode = ((Activity) getActivity()).startActionMode(mActionModeCallback);
animateRow(position);
checked.put(position, true);
mActionMode.setTitle("1");
mActionMode.getMenu().getItem(0).setVisible(true);
} else {
animateRow(position);
if (checked.get(position)) {
checked.put(position, false);
if (checked.indexOfValue(true) < 0) {
mActionMode.finish();
} else {
mActionMode.setTitle(String.valueOf(getCheckedCount()));
}
} else {
checked.put(position, true);
mActionMode.setTitle(String.valueOf(getCheckedCount()));
}
}
}
}
);
Then the animateRow() method:
private void animateRow(final int position) {
if (position >= listView.getFirstVisiblePosition() && position <= listView.getLastVisiblePosition()) {
Log.i("animateRow", String.valueOf(position));
ScaleAnimation anim = new ScaleAnimation(1, 0, 1, 1, Animation.RELATIVE_TO_SELF, 0.5f, 0, 0);
anim.setDuration(150);
anim.setRepeatCount(1);
anim.setRepeatMode(Animation.REVERSE);
viewa = listView.getChildAt(position - listView.getFirstVisiblePosition());
final Button chkButton = (Button) viewa.findViewById(R.id.logo);
if (checked.get(position)) {
anim.setAnimationListener(
new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.i("anim" + position, "Start");
}
#Override
public void onAnimationRepeat(Animation animation) {
Log.i("anim" + position, "Repeat" + animation.getRepeatCount());
viewa.setBackgroundResource(R.color.row_background);
chkButton.setBackgroundResource(R.color.button_background);
chkButton.setText(String.valueOf(alllists.get(position).itemsCount));
}
#Override
public void onAnimationEnd(Animation animation) {
Log.i("anim" + position, "END");
}
}
);
chkButton.startAnimation(anim);
} else {
anim.setAnimationListener(
new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
Log.i("anim" + position, "Start");
}
#Override
public void onAnimationRepeat(Animation animation) {
viewa.setBackgroundResource(R.color.checked_row_background);
chkButton.setBackgroundResource(R.color.checked_button_background);
chkButton.setText("✓");
}
#Override
public void onAnimationEnd(Animation animation) {
Log.i("anim" + position, "END");
}
}
);
chkButton.startAnimation(anim);
}
}
}
I hope it helps.. :)
Now you can forget that method to flip a view, since I've developed a new library FlipView fully customizable, this is exactly what you want. You will be able to swap any kind of views and layouts with any kind of animation you desire.
Please have a look.
Hi have a problem with Animation, actually i want to fade my ImageView while it's changing it resource.
It's not working, i can change the resource but without any animation.
private void checkX() {
// TODO Auto-generated method stub
switch (x) {
case (1): {
startingAnimation();
xImg.setImageResource(R.drawable.test_uno);
endingAnimation();
break;
}
case (2): {
startingAnimation();
xImg.setImageResource(R.drawable.test_due);
endingAnimation();
break;
}
case (3): {
startingAnimation();
xImg.setImageResource(R.drawable.test_tre);
endingAnimation();
break;
}
case (4): {
startingAnimation();
xImg.setImageResource(R.drawable.test_quattro);
endingAnimation();
break;
}
case (5): {
x = 1;
checkX();
break;
}
case (0): {
x = 4;
checkX();
break;
}
}
}
private void endingAnimation() {
// TODO Auto-generated method stub
ObjectAnimator animation2 = ObjectAnimator.ofFloat(xImg, "alpha", 255);
animation2.setDuration(1000);
animation2.start();
}
private void startingAnimation() {
// TODO Auto-generated method stub
ObjectAnimator animation = ObjectAnimator.ofFloat(xImg, "alpha", 0);
animation.setDuration(1000);
animation.start();
}
checkX is called each time i press a button(that add or subtract 1 to X).
How i can make both animations and ImageView resource change?
Try changing the image source when the animation's onAnimationEnd is called. For example:
animation.addListener(new AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) { }
#Override
public void onAnimationRepeat(Animator animation) { }
#Override
public void onAnimationEnd(Animator animation) {
// change your ImageView's source here
}
#Override
public void onAnimationCancel(Animator animation) { }
});
Apply fade out animation on your ImageView and set animationListener to it. on animation end change your views resource and set fade in animation on it
For fade in animation
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(1000);
final AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeIn);
For fade out animation
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(300);
final AnimationSet animation = new AnimationSet(false);
animation.addAnimation(fadeOut);
Thats how you implement listner on animation
fadeout.setAnimationListener(new Animation.AnimationListener(){
#Override
public void onAnimationStart(Animation arg0) {
}
#Override
public void onAnimationRepeat(Animation arg0) {
}
#Override
public void onAnimationEnd(Animation arg0) {
//change resource of Imageview here
}
});