I'm using RotateAnimation and TranslateAnimation in my game project. After completing rotate i'm saving image next using TranslateAnimation. It works fine, but completing rotateanimation the image blinks once.
public void Trainplace(int x,int y,Bitmap b){
param.setMargins(x, y, 0, 0);
Train.setLayoutParams(param);
Train.setImageBitmap(b);
Train.setVisibility(0);
}
public void Trainmove(int x){
TAnimation=new TranslateAnimation(0, 0, 0,x);
TAnimation.setInterpolator(new LinearInterpolator());
TAnimation.setDuration(2000);
TAnimation.setFillAfter(true);
//TAnimation.setFillBefore(true);
Train.startAnimation(TAnimation);
}
public void Trainrotate(int a,int b,int c,int d){
RAnimation=new RotateAnimation(a,b,c,d);
RAnimation.setInterpolator(new LinearInterpolator());
RAnimation.setDuration(2000);
RAnimation.setFillAfter(true);
Train.startAnimation(RAnimation);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.b:
Trainplace(20, 255,bmpy1);
Trainrotate(0,90,50,25);
//Stop button clicks
//B.setEnabled(false);
break;
case R.id.b2:
Trainplace(35, 230,bmpx1);
Trainrotate(0,-90,20,-30);
RAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation arg0) {
}
public void onAnimationRepeat(Animation arg0) {
}
public void onAnimationEnd(Animation arg0) {
int p=0;
while(p<=1){
if(RAnimation.hasEnded()){
Toast.makeText(getApplicationContext(), "End", Toast.LENGTH_SHORT).show();
p=2;
}
}
Trainplace(85, 170,bmpy1);
Trainmove(-100);
}
});
break;
My problem is with completing the rotateanimation - the current image is replaced by another image (ex. my train image rotated 90 degrees then i m placed 90 degrees rotated image in that place )and then move forward by using Translateanimation this is working.
When placing the image inbetween, after completing Rotateanimation and before starting Translateanimation the train image is blinking once.
The same image will place with noproblem (means Translateanimation to Rotateanimation).
When I get blinks in animation, its most probably because the animation listeners 'onAnimationEnd' is firing before the animation is actually done.
You can create av custom view or layout and overide its 'animationEnd' method and add a interface so you can set up a listener.
Here's an example
CustomLayout class
public class CustomLayout extends LinearLayout {
private LayoutAnimationListener mListner;
public CustomLayout(Context context) {
super(context);
}
public CustomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onAnimationEnd() {
super.onAnimationEnd();
if(mListner != null){
mListner.onAnimationEnd(CustomLayout.this);
}
}
#Override
protected void onAnimationStart() {
super.onAnimationStart();
if(mListner != null){
mListner.onAnimationStart(CustomLayout.this);
}
}
public static interface LayoutAnimationListener {
//Notifies the start of the animation.
void onAnimationStart(CustomLayout cLayout);
//Notifies the end of the animation.
void onAnimationEnd(CustomLayout cLayout);
}
public void setLayoutAnimationListener(LayoutAnimationListener listener){
mListner = listener;
}
}
So in your activity you can use it as a normal linearlayout and instead of adding a animation listener to the animation, you can add it to the layout like
com.blessan.CustomLayout layout =
(com.blessan.CustomLayout)findViewById(R.id.counts_layout);
LayoutAnimationListener layoutAnimListener = new LayoutAnimationListener() {
#Override
public void onAnimationStart(CustomLayout cLayout) {
}
#Override
public void onAnimationEnd(CustomLayout cLayout) {
}
};
layout.setLayoutAnimationListener(layoutAnimListener);
This might work for you. Give it a try.
Related
I have repeatedly defined animation in this code. Is not there a simpler way to do this? the code works the way I want it, but I want to simplify my encoding.can you help me. How should I follow a method. How to add wait time?
I made a code that I could not do in this title but it came to be written much shorter
resimyukle();
hediye=getDrawable(R.drawable.hediye);
final ImageView[] imajlar={img1,img2,img3,img4,img5,img6,img7,img8};
Animation fadein=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
imajlar[0].setBackground(hediye);
imajlar[0].startAnimation(fadein);
Animation res=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
Animation res1=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
Animation res2=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
Animation res3=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
Animation res4=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
Animation res5=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
Animation res6=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
anima(fadein,res,imajlar[1]);
anima(res,res1,imajlar[2]);
anima(res1,res2,imajlar[3]);
anima(res2,res3,imajlar[4]);
anima(res3,res4,imajlar[5]);
anima(res4,res5,imajlar[6]);
anima(res5,res6,imajlar[7]);
}
public void anima(final Animation aa, final Animation bb, final ImageView img)
{
aa.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
animation.cancel();
img.setBackground(hediye);
img.startAnimation(bb);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
hediye=getDrawable(R.drawable.hediye);
final ImageView[] imajlar={img1,img2,img3,img4,img5,img6,img7,img8};
Animation res=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fadein);
for (int i = 0; i < imajlar.size; i++) {
anima(res, imajlar[i], i);
}
And your method:
public void anima(Animation aa, ImageView img, int id)
{
aa.setStartOffset(id * 500);
aa.setDuration(1000);
img.startAnimation(aa);
img.setBackground(hediye);
}
I would like to apply the same alphaanimation for button A, B and C, and therefore implemented the following codes:
public void onCreate(Bundle savedInstanceState)
{
animation = new MutableAlphaAnimation();
animation.setAnimationListener(this);
btn_A.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
animation.setResetBlocked(true);
btn_A.setAnimation(animation);
animation.setResetBlocked(false);
animation.start(0.0f, 0.5f, FADE_IN_DURATION);
btn_A.invalidate();
}
});
}
public class MutableAlphaAnimation extends Animation
{
private float mFromAlpha;
private float mToAlpha;
private boolean resetBlocked;
public MutableAlphaAnimation()
{
}
public void start(float fromAlpha, float toAlpha, long duration)
{
mFromAlpha = fromAlpha;
mToAlpha = toAlpha;
setDuration(duration);
setStartTime(START_ON_FIRST_FRAME);
}
public void setResetBlocked(boolean resetBlocked)
{
this.resetBlocked = resetBlocked;
}
#Override
public void reset()
{
if (! resetBlocked) super.reset();
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
final float alpha = mFromAlpha;
t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
}
#Override
public boolean willChangeTransformationMatrix()
{
return false;
}
#Override
public boolean willChangeBounds()
{
return false;
}
}
Question:
btn_A, B and C are implemented with the same setOnClickListener. However, when they are pressed, nothing happen. Why? How can the above be modified?
Thanks!
You aren't applying your transformation to btn_home. Yes you set the it to the animation, but your animation class never touches btn_home. Your t.setAlpha... should really be btn_home.setAlpha..., so pass in the view using the constructor and then you can use it with any view in the future.
I want to play one animation with multiple views in android.
This is the simplified example of code.
This code works incorrectly.
Every startAnimation() call, affects all previously animated views
Please tell me, why it doesn't works and how to make it properly.
public SomeClass() {
private int currentViewID = 0;
private View[] views = { view1, view2, view3, view4, view5 }
private Animation anim = AnimationUtils.loadAnimation(this.getContext(), android.R.anim.fade_out);
public SomeClass() {
this.anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
if (SomeClass.this.currentViewID != SomeClass.this.views.length) SomeClass.this.hideNextView();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
this.hideNextView();
}
private void hideNextView() {
this.views[this.currentViewID++].startAnimation(this.anim);
}
}
If you don't want to deal with many Animations in your class (one for each View) you could do things locally:
private int currentViewID = 0;
private View[] views = { view1, view2, view3, view4, view5 }
public SomeClass() {
this.hideNextView();
}
private void hideNextView() {
final Animation anim = AnimationUtils.loadAnimation(this.getContext(), android.R.anim.fade_out);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
if (SomeClass.this.currentViewID != SomeClass.this.views.length) SomeClass.this.hideNextView();
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationStart(Animation animation) {}
});
this.views[this.currentViewID++].startAnimation(anim);
}
I am trying to animate an ImageButton. When the button is clicked, I want it to slide to the right. When it's clicked again, it should slide back to its original position.
When the animation ends it goes back to the original position therefore I reposition the ImageButton. I have a small "flash" where both the ImageButton and the animation is at the original position before the ImageButton has been repositioned. Can anyone tell me how to get rid of this "flash"?
I have written the following code to start the animations and when the animation ends, move the ImageButton itself.
What it is, is an onClickListener for sliding the ImageButton in and an AnimationListener for this. There's also an onClickListener and an AnimationListener for sliding the ImageButton back.
private class SceneIndicatorListenerIn implements ImageButton.OnClickListener {
ImageButton imageButton;
public SceneIndicatorListenerIn (ImageButton imageButton) {
this.imageButton = imageButton;
}
#Override
public void onClick(View view) {
// Create animation
Animation anim = AnimationUtils.loadAnimation(context, R.anim.sceneindicator_in);
anim.setAnimationListener(new SceneIndicatorListenerInDidEnd(imageButton));
view.startAnimation(anim);
}
}
private class SceneIndicatorListenerInDidEnd implements AnimationListener {
ImageButton imageButton;
public SceneIndicatorListenerInDidEnd (ImageButton imageButton) {
this.imageButton = imageButton;
}
#Override
public void onAnimationEnd(Animation anim) {
Log.d(LOG_TAG, "In animation did end");
// This is for density pixels
float dp = context.getResources().getDisplayMetrics().density;
// Keep position after animation
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(imageButton.getWidth(), imageButton.getHeight());
params.setMargins((int) (0 * dp), imageButton.getTop(), 0, 0);
imageButton.setLayoutParams(params);
// Change on click listener
imageButton.setOnClickListener(new SceneIndicatorListenerOut(imageButton));
}
#Override
public void onAnimationRepeat(Animation arg0) {}
#Override
public void onAnimationStart(Animation arg0) {}
}
private class SceneIndicatorListenerOut implements ImageButton.OnClickListener {
ImageButton imageButton;
public SceneIndicatorListenerOut (ImageButton imageButton) {
Log.d(LOG_TAG, "My imageButton was set");
this.imageButton = imageButton;
}
#Override
public void onClick(View view) {
Log.d(LOG_TAG, "You clicked me");
// Create animation
Animation anim = AnimationUtils.loadAnimation(context, R.anim.sceneindicator_out);
anim.setAnimationListener(new SceneIndicatorListenerOutDidEnd(imageButton));
view.startAnimation(anim);
}
}
private class SceneIndicatorListenerOutDidEnd implements AnimationListener {
ImageButton imageButton;
public SceneIndicatorListenerOutDidEnd (ImageButton imageButton) {
this.imageButton = imageButton;
}
#Override
public void onAnimationEnd(Animation anim) {
Log.d(LOG_TAG, "Out animation did end");
// This is for density pixels
float dp = context.getResources().getDisplayMetrics().density;
// Keep position after animation
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(imageButton.getWidth(), imageButton.getHeight());
params.setMargins((int) (-199 * dp), imageButton.getTop(), 0, 0);
imageButton.setLayoutParams(params);
// Change on click listener
imageButton.setOnClickListener(new SceneIndicatorListenerIn(imageButton));
}
#Override
public void onAnimationRepeat(Animation arg0) {}
#Override
public void onAnimationStart(Animation arg0) {}
}
This is my animation for sliding in:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%"
android:toXDelta="83%"
android:duration="750" />
</set>
And this is my animation for sliding back:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%"
android:toXDelta="-80%"
android:duration="750" />
</set>
I had this same issue and wanted to post the answer for anyone who encounters this. There is a bug that causes this no matter what you set in xml or otherwise.
The way I got around it was the manually set the X location off of the screen before the animation so that the flash would happen off of the screen, then it would be set back to it's original position as being processed by the animation.
image.setX(-5000);//Really any number off of the screen will do
Animation animation0 = AnimationUtils.loadAnimation(this,
R.anim.slide_across_right);
animation0.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
animationHack();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
private void animationHack() {
(new Handler()).postDelayed(new Runnable() {
public void run() {
image.setX(0);
}
}, 20);
}
I have created an animation using the following code.
private AnimationSet rootSet = new AnimationSet(true);
private int xstart=258;
private int ystart=146;
for(; k<points.length; k++) {
if(k==1) {
x1 = headX(xstart);
y1 = headY(ystart);
_animTime = 10;
} else {
x1 = headX(points[k-1][0]);
y1 = headY(points[k-1][1]);
}
translate = new TranslateAnimation((float)x1, (float)x2, (float)y1, (float)y2);
translate.setDuration(_animTime);
translate.setFillAfter(true);
translate.setInterpolator(new AccelerateDecelerateInterpolator());
totalAnimTime += _animTime;
translate.setStartOffset(totalAnimTime);
rootSet.addAnimation(translate);
rootSet.setFillAfter(true);
}
imv1.startAnimation(rootSet);
It is working fine. Now I have to add pause and play feature for this animation. How can I do that?
Since you have extended with more information regarding that you explicity wanted to use AnimationSet, I have found another solution that should work for you.
Sample code:
A class that extends AnimationSet as you will need in order to cancel an AnimationSet:
public class CustomAnimationSet extends AnimationSet {
private AnimationListener mCustomAnimationSetListener;
public CustomAnimationSet(boolean interpolator) {
super(interpolator);
}
public CustomAnimationSet(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void setAnimationListener(AnimationListener listener) {
super.setAnimationListener(listener);
mCustomAnimationSetListener = listener;
}
/**
* Your cancel method....
*/
public void cancel() {
// Make sure you're cancelling an ongoing AnimationSet.
if(hasStarted() && !hasEnded()) {
if(mCustomAnimationSetListener != null) {
mCustomAnimationSetListener.onAnimationEnd(this);
}
}
// Reset the AnimationSet's start time.
setStartTime(Float.MIN_VALUE);
}
}
In your Activity class:
private CustomAnimationSet mAnimationSet;
// Init stuff.
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.onPlayButton:
// Might wanna add Animations before starting next time?
mAnimationSet.start();
case R.id.onPauseButton:
mAnimationSet.cancel();
mAnimationSet.reset();
}
}
This is just an example. At the moment I do not have opportunity to test it by myself, this was just written for example purpose.