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
Related
I am trying to develop an app that takes a 15 seconds of video, allows the user to apply different filters, shows the preview of the effect, then allows to save the processed video to sdcard. I use ffmpeg to split the video into JPEG frames, apply the desired filter using GPUImage to all the frames, then use ffmpeg to encode the frames back to a video. Everything works fine except the part where user selects the filter. When user selects a filter, the app is supposed to display the preview of the video with the filter applied. Though 450 frames get the filter applied fairly quick, displaying the images sequentially at 30 fps (to make the user feel the video is being played) is performing poorly. I tried different approaches but the maximum frame rate I could attain even on the fastest devices is 10 to 12 fps.
The AnimationDrawable technique doesn't work in this case because it requires the entire images to be buffered into memory which in this case is huge. App crashes.
The below code is the best performing one so far (10 to 12 fps).
package com.example.animseqvideo;
import ......
public class MainActivity extends Activity {
Handler handler;
Runnable runnable;
final int interval = 33; // 30.30 FPS
ImageView myImage;
int i=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myImage = (ImageView) findViewById(R.id.imageView1);
handler = new Handler();
runnable = new Runnable(){
public void run() {
i++; if(i>450)i=1;
File imgFile = new File(Environment.getExternalStorageDirectory().getPath() + "/com.example.animseqvideo/image"+ String.format("%03d", i) +".jpg");
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
myImage.setImageBitmap(myBitmap);
}
//SOLUTION EDIT - MOVE THE BELOW LINE OF CODE AS THE FIRST LINE OF run() AND FPS=30 !!!
handler.postDelayed(runnable, interval);
}
};
handler.postAtTime(runnable, System.currentTimeMillis()+interval);
handler.postDelayed(runnable, interval);
}
}
I understand that the process of getting an image from SDCard, decoding it, then displaying it onto the screen involves the performance of the SDCard reading, the CPUs performance and graphics performance of the device. But I am wondering if there is a way I could save a few milliseconds in each iteration. Any suggestion would be of great help at this point.
I also did a similar thing. I used a ValueAnimator. The images is an array of the image ids. eg: R.drawable.park1
ValueAnimator animation = ValueAnimator.ofInt(0,44);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(1000);
animation.setRepeatCount(200);
animation.addUpdateListener(new AnimatorUpdateListener() {
int i;
public void onAnimationUpdate(ValueAnimator animation) {
Log.i("TAG", "::onAnimationUpdate: "+(++i)+" value = "+animation.getAnimatedValue());
mImageViewPreview.setImageResource(images[(Integer) animation.getAnimatedValue()]);
mImageViewPreview.invalidate();
if(mImageViewPreview.getVisibility()!=View.VISIBLE){
animation.cancel();
}
}
});
animation.start();
You are correct in saying that the performance of SDCard reading is slow. In fact look at how many things you want done - creating a new file from an external location, decoding it and creating a new bitmap. And all this done on the UI thread.
I don't know how big your images are but have you tried possibly preloading some of them, putting them in a list and then just picking them from that list and displaying them in your handler code?
I realize storing 450 images in memory is quite a lot but the task could probably be split up. Say you have preload 100 bitmaps and start displaying them, and then have an Async Task preloading the other 100 into the next list(or possibly the same list) at the same time.
My Bad ! Found the culprit. Being used to NSTimer on iOS, I overlooked the importance of the line of code :
handler.postDelayed(runnable, interval);
That code responsible for scheduling the next frame process was being executed AFTER the current frame getting read from the SDCard, decoded and displayed on to the imageview.
ie. If the entire process of displaying the current frame took 25 milliseconds, the next frame processing would be scheduled after 25+33 = 58ms after previous frame.
I moved that line of code to the first line of the run{} method of the runnable thread , and BINGO !! FPS raised to 24-30 FPS even on a $100 android device.
Anyways thanks to #Valentin, #Pedro Bernardo and #Shashika for pointing out some valid possible solutions.
The strangest thing is happening. In my onClick(View ...) I have blocks of code, mostly 'if/else' blocks. The sequence is (in pseudo-code, to save you lengthy code):
I have an image that needs setting using imageButton.setImageResource(randomImage); then
I have a MediaPlayer associated with this image that needs playing, then
I place a sleep(1800) here otherwise the MediaPlayer runs into the next MediaPlayer (this works fine)
This image is compare to another image. If its not the same, then another MediaPlayer named 'boo' is played, and the image that should have been displayed in code 1. above, is replaced by 'flag' image. else //if its the right image then
Switch to 'another' image, play it's corresponding MeidaPlayer, Play a 'cheers' MediaPlayer and change image to a 'tick' image, then do some other logic stuff.
But what is happening is that the code 2. is playing, code 3. is happening. code 4. only the 'boo' mediaplayer is happening and I notice the imagebutton flashing. The image that was supposed to be set in code 1. is delayed and is happening only AFTER the 'boo' mediaplayer. The 'flag' image that replaces the first image setting in code 1. is happening but because code 1. is in delay, what is happening is that the image is not changing (although it is, it's just in delay and then it flashes so quickly that it appears not to change). So code 1. is in delay.
Also, if it goes into the else and the right image is clicked, then the image in code 5. DOES switch to 'another', but the corresponding MeidaPlayer doesn't play, the 'cheers' MediaPlayer doesn't play, the 'tick' image doesn't display, and the other logic doesn't occur. Its as if it is ignoring the code.
What's happening here? Is this a multi-threading situation here? Grouping different parts of the code in their own threads and starting them at once only throws exceptions. Any help will be greatly appreciated!
If you want to delay your code, use Handler.postDelayed(Runnable, long). This won't block the UI thread, and will execute when you want it to.
Whitout your code, it's really unclear what are you trying to achive, and how are you trying to achieve it.
Just to explain Adam's idea.
Put this in your Activity class :
final Handler handler = new Handler();
Runnable _rnbl = new Runnable() {
public void run() {
// Your code
}
};
And call it like this
handler.postDelayed(_rnbl , 5000);
I am working on game application and i use AnimationDrawable for image change.
but problem is i want imageview invisible when Animation is finish.so what should i do
for this.
My code is like this...
mAnimation = new AnimationDrawable();
mAnimation.addFrame(getResources().getDrawable(R.drawable.d5),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d4),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d3),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d2),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d1),150);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d2),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d3),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d4),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.d5),50);
mAnimation.addFrame(getResources().getDrawable(R.drawable.new_transparent),50);
mAnimation.setOneShot(true);
mDogImage.setImageDrawable(mAnimation);
Thanks in advance.
There is no event or listener that will notify you.You just need to apply the trick
Use mAnimation.getNumberOfFrames(); to get total number of frames and since each frame will last long for 50ms.So your animation is supposed to end in mAnimation.getNumberOfFrames() * 50 ms.
For eg if you have 9 frames and each frame has duration of 50ms then your animation is going to end in 450ms.
So conclusion will be you will make your ImageView invisible after 450ms once animation starts.
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();
}
}
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();