I have a set of 10 images, and I want to create an animation where I cross fade between them. I've been looking into built-in Drawable to achieve such a thing, but no luck on that part.
There is the AnimationDrawable, that switch between pictures, but it doesn't animate the switch.
There is the TransitionDrawable, that cross fade between two pictures, but no more than two.
Hell.
I looked for some solution on Google, but no luck on that part. So I'm thinking about implementing my own drawable to achieve such a thing. Would any of you have any pointers ?
Thanks in advance.
Not sure if you found an answer to this, but I had the same problem and ended up building my own class based on TransitionDrawable.
Usage:
CyclicTransitionDrawable ctd = new CyclicTransitionDrawable(new Drawable[] {
drawable1,
drawable2,
drawable3,
...
});
imageView.setImageDrawable(ctd);
ctd.startTransition(1000, 3000) // 1 second transition, 3 second pause between transitions.
The code for the CyclicTransitionDrawable is available on Github.
Well. Long time has passed, and you probably fixed the issue, but you got setEnterFaceDuration() for AnimationDrawable. Example:
mBackgroundAnimation = new AnimationDrawable();
mBackgroundAnimation.addFrame(getResources().getDrawable(R.drawable.background1), 5000);
// ... rest of the frames
mBackgroundAnimation.addFrame(getResources().getDrawable(R.drawable.background6), 5000);
mBackgroundAnimation.setEnterFadeDuration(1000);
mBackgroundAnimation.setOneShot(false);
With this code you have an easy cycling through 1..N images, each one remains 5s (5000ms) with a fade-in animation. Now, what i do is setting the background of my root RelativeLayout
mLayoutRoot.setBackground(mBackgroundAnimation);
mLayoutRoot.post(new AnimationStarterThread());
And the AnimationStarterThread class
private class AnimationStarterThread implements Runnable {
public void run() {
if(mBackgroundAnimation != null)
mBackgroundAnimation.start();
}
}
Related
I'm trying to create an Android app that will include many (sometimes up to about 200) small images that will be animated (relocate and change size) about 20 at a time. After that they'll remain still.
Should I use the simple solution of the View class animation or should I use Drawable animation?
EDIT: I should be more specific..
There are a lot of tutorial out there and a lot of different ways to do the same thing. I'm looking for the best way to implement the next scenario:
Say I have 50 different small (30x30) images currently drawn on the screen.
I need to animate them so they will translate to a different DYNAMIC position. And while they are moving I need the image to be resized up and down (so I get kind of a jump effect if looking from top).
They need to move within a specific timeframe. For example: After the first image starts to move, the second will begin moving 50ms after the last and so on (wave effect)...
After one group of images is translated, another group will be formed, but the last group will still be on screen.
So what I'm asking is a little specifics about the best way to do this. For example: Should I create a XML file for each Image or should I just load them in code? Should I load all the images (there could be up to 200 small images, maybe more) at application start or will it be ok to load them on demand? What would be the best animation technique? Stuff like that.
The easiest solution I found: (API 16+)
Runnable endAction = new Runnable() {
public void run() {
tv.animate().x(400).y(1400).scaleX(1).scaleY(1);
}
};
tv.animate().x(600).y(100).scaleX(3).scaleY(3).withEndAction(endAction);
I would use Drawable animation but it doesn´t matter so much. The important thing you should do if the app runs very slow, is to use diferents threads using this code for example:
Handler mHandler = new Handler();
mHandler.post(new Runnable() {
public void run() {
//YOUR ANIMATION HERE
}
});
In this way, you will be able to process the animation of a lot of images at the same time because the phone will execute the code in different computing threads.
You can use too AsyncTask like that (adding the class into your activity class):
private class doAnimation extends AsyncTask<ImageView, Void, Void>{
#Override
protected Void doInBackground(ImageView... image) {
image.startAnimation(animation);
return null;
}
}
And calling it using:
new doAnimation().execute(image1);
new doAnimation().execute(image2);
new doAnimation().execute(image3);
...
I have an AnimatedSprite that after it finishes the animation I want to reverse animate it. I want to do that continuously. Once the reverse animation is complete I want to play the original one. This may be easy one but I am new to Android and AndEngine.
mFlower1Sprite = new AnimatedSprite(20, 800, this.mFlower1);
mFlower1Sprite.setScale((float) 1.5);
mFlower1Sprite.animate(500, 0, new IAnimationListener () {
public void onAnimationEnd(final AnimatedSprite pAnimatedSprite) {
// reverse animation
}
});
mScene.attachChild(mFlower1Sprite);
return mScene;
Use animate method:
public AnimatedSprite animate (long[] pFrameDurations, int[] pFrames,
int pLoopCount, AnimatedSprite.IAnimationListener pAnimationListener)
Animate specifics frames.
Parameters:
pFrameDurations must have the same length as pFrames.
pFrames indices of the frames to animate.
Simply list the indices in reverse order.
I'm working with sprites myself atm and I came across this jQuery plugin. Check it out.
http://spritely.net/
I'm not aware of any support to reverse the frames of an AnimatedSprite, although it's probably a useful feature so I'd love to find out if I'm wrong.
Your best bet would probably be to create another sprite sheet with the frames reversed and another instance of an AnimatedSprite for that sheet. Then define one or two private IAnimationListeners inside your activity (rather than on the fly when you call .animate()), which alternately detach and attach the two sprites at the end of each animation.
I was trying to make an into transition to my game by having two bitmaps slide apart, like a garage door opening from the middle and half sliding downwards and half upwards. Anyway, when I do it, it looks really choppy and the frame rate seems unstable/unreliable. Here's how I'm doing it.
public class TFView extends View{
...
public void startlevel(Canvas c){
long l =(SystemClock.currentThreadTimeMillis()-starttime)/3;//*(height/500);
if(l<1000){
c.drawBitmap(metalbottom,0,height/2+l,p);
c.drawBitmap(metaltop,0,0-l,p);}
}
public void endlevel(Canvas c){
long l =(SystemClock.currentThreadTimeMillis()-failtime)/3;
if(l>=height/2){
c.drawBitmap(metaltop, 0, 0, p);
c.drawBitmap(metalbottom, 0,height/2 , p);
}
else{
c.drawBitmap(metalbottom,0,-height/2+l,p);
c.drawBitmap(metaltop,0,height-l,p);}
}}
and i set the times for when I want to open/close the doors respectively. So what do you think I should change to make it a more smooth transition? Would converting it to surfaceview help?
I had the same problem. I know what you mean with "choppy". The animation speed is NOT consistent even though you have a time based animation i.e. you are using
SystemClock.currentThreadTimeMillis()
The choppiness is caused by currentThreadTimeMillis(). It "returns milliseconds running in the current thread". That is, when you use currentThreadTimeMillis() "time" only elapses when the current thread is RUNNING. But your renderer thread is NOT ALWAYS running - as you would expect in a multitasking environment. Thus every time the thread is not running your animation is also not "running" (time is not elapsing).
Solution: Use
SystemClock.elapsedRealtime()
I have to admit I'm not the best when it comes to animation in Android but I thought I'd contribute.
From your explanation, could you use TranslateAnimation? Your animation would then be very smooth.
As far as I'm aware, if the animations Android provides are not sufficient you should be drawing your graphics in a separate thread, implementing SurfaceView.
This may help or take a look at the Lunar Lander example.
I want to start 5 different frame animations:One for cap,one for scarf
one for character,one fro face Expressions and one for scarf borders.I want it to look like man is running with scarf hat.Animations started fine,
but all animations are not playing at same time.
Please help me to do that.
I set the png images through addFrame method in my code .
I am posting the sample code here
capanimation.setVisible(true,true);
capanimation.start();
Log.i("fani"," cap: "+System.currentTimeMillis() );
scarfmainanimaiton.setVisible(true,true);
scarfmainanimaiton.start();
Log.i("fani"," sca: "+System.currentTimeMillis() );
faceexpressionanimation.setVisible(true,true);
faceexpressionanimation.start();
Log.i("fani"," fac: "+System.currentTimeMillis() );
charecteranimation.setVisible(true,true);
charecteranimation.start();
Log.i("fani"," cha: "+System.currentTimeMillis() );
I think you can do this using frame by frame animation which is very easy. I will provide link for that check http://developer.android.com/guide/topics/graphics/drawable-animation.html
In that you can put your images in resources folder and that can animated as per requirement. Hope this will help you.
In may app i am giving choice to user to select cap,scarf among different options
based on the user selection i need to animate that cahrecter with user selcted cap and scarf
//Iam posting the some sample code here
public int maledance[]={R.drawable.char01,R.drawable.char02,R.drawable.char03,R.drawable.char04,R.drawable.char05,R.drawable.char06
,R.drawable.char07,R.drawable.char08,R.drawable.char09,R.drawable.char10,R.drawable.char11,R.drawable.char12,R.drawable.char13,R.drawable.char14,R.drawable.char15};
public int maledancescarf1[]={R.drawable.scarve101,R.drawable.scarve102,R.drawable.scarve103,R.drawable.scarve104,R.drawable.scarve105,R.drawable.scarve106,
R.drawable.scarve107,R.drawable.scarve108,R.drawable.scarve109,R.drawable.scarve110,R.drawable.scarve111,R.drawable.scarve112,R.drawable.scarve113,R.drawable.scarve114,R.drawable.scarve115};
etc......
charecteranimation=new AnimationDrawable();
capanimation=new AnimationDrawable();
capboarderanimation=new AnimationDrawable();
scarfmainanimaiton=new AnimationDrawable();
scarfboarderanimation=new AnimationDrawable();
faceexpressionanimation=new AnimationDrawable();
for(int i=0;i<maledance.length;i++)
{
Log.i("fani","string lenth is "+maledance.length+" delay is "+delay);
charecteranimation.addFrame(getResources().getDrawable(maledance[i]),t);
capanimation.addFrame(getResources().getDrawable(maledancecap[i]),t);
scarfmainanimaiton.addFrame(getResources().getDrawable(maledancescarf[i]),t);
faceexpressionanimation.addFrame(getResources().getDrawable(malefaceexpression[i]),t);
}
capanimation.setOneShot(false);
charecteranimation.setOneShot(false);
scarfmainanimaiton.setOneShot(false);
faceexpressionanimation.setOneShot(false);
//in onwindowfocuschanged listner i am starting the animations
I'm creating a gallery view where I'm loading images from the web. While the images are loading, I want to display an animation as a placeholder for each image. I figured this could be done using an AnimationDrawable, however, the animation won't start. The first frame of the animation loads as expected, and if I use the same in for example onWindowFoucsChanged in an activity, everything works fine.
Inside the getView method of my GalleryItemCursorAdapter (which extends SimpleCursorAdapter) I'have the following snippet:
AnimationDrawable frameAnimation = (AnimationDrawable) mContext.getResources().getDrawable(R.drawable.loading);
holder.picture.setImageDrawable(frameAnimation);
frameAnimation.setCallback(holder.picture);
frameAnimation.setVisible(true, true);
frameAnimation.start();
holder.picture is an ImageView. I get no errors, and (very) similar code seems to work fine other places, leading me to believe this may be related to similar to the onCreate issues for animations reported elsewhere. I've tried some variations of the above code, too.
My questions:
Is there an easier/better way to display a loading animation?
What can I do to make the above example work (if at all possible)?
create a new thread and start ..
new Thread(new Runnable() {
public void run(){
// some code that runs outside the ui thread.
frameAnimation.start();
}
}).start();