Android Animation with onDraw or ImageView? - android

I want to create an android game. Everytime someone touches the display the player should go up, and if he releases the player should fall.
With the help of many tutorials I made it work but now I want to animate it and I'm stuck. That means the image of the player should be changed every half a second. Additionally an animated rotation should be created when the player goes up.
However (after hours of googling) I couldnt find any helpful answer to my problem. The Android Developers site talks about creating an ImageView and a XML file. But thats where I'm stuck: I dont have an ImageView, my player (for which I used a PNG file) is simply created by the onDraw() method:
public void onDraw(Canvas canvas) {
for (Sprite s : sprites) {
canvas.drawBitmap(s.getGraphic(), s.getLocation().x,
s.getLocation().y, null);
}
}
Now I wanted to ask how I should do the animation and the animated rotation. Should I start off with an ImageView or can I somehow "convert" the onDraw method to an ImageView? Or is there another way to do the animation and animated rotation without an ImageView?
Secondly, if I had to create the ImageView I don't understand how I can make the player "dynamic", i.e.: changing the position when someone touches the display.
Thanks in advance :)
EDIT:
Ok, I created my animation.xml file in the drawable folder:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" android:id="#+id/splashAnimation">
<item android:drawable="#drawable/ship" android:duration="200" />
<item android:drawable="#drawable/ship_2" android:duration="200" />
</animation-list>
and in my main file I added:
ImageView img = (ImageView) findViewById(R.id.splashAnimation);
img.setBackgroundResource(R.drawable.animation);
ship_anim= (AnimationDrawable) img.getBackground();
ship_anim.start();
However, now I get the error message: NullPointerException
Where is the Problem?

if you have drawables that describe animation, you can always create xml in your drawable folder like this than add this as imageView to the layout
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/img1" android:duration="100" />
<item android:drawable="#drawable/img2" android:duration="100" />
<item android:drawable="#drawable/img3" android:duration="100" />
<item android:drawable="#drawable/mimg4" android:duration="100" />
<item android:drawable="#drawable/img5" android:duration="100" />
</animation-list>
The code for it would look like this:
myAnimation = (AnimationDrawable) findViewById(R.id.animation);
Add just event handler than
if (!isPlaying)
{
playDrawableAnimation();
isPlaying = true;
} else
{
faceAnimation.stop();
isPlaying = false;
}

Related

Button animations in Android

Today I got, as I suppose, very interesting question. On my job we are creating a dating service and one of the main features will be the screen, where photos of different girls (or guys) are shown and the user press either "Hot" or "Not" button. Both of these buttons are displayed below the photo on the screen.
Our analytics say that we should implement some kind of "gaming" mechanics, so the want such a thing: when user press, for example, "Not" button - it starts freezing and covering with ice, then it breaks and then the next photo is shown. That is not scale or rotate or translate animation... the button itself, its content should be changing over some small period of time (a second or two maybe).
That scares me a lot, because when I'm thinking about scaling these buttons on different devices, and different troubles with ninepatch and hand-made-frames animations I'm likely going to make.
Is it possible to make such thing? Or maybe there are any kind of workarounds or something.
Make images for your animation and keep in a folder in png format.
Animate those images with code below.
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="#drawable/rocket_thrust1" android:duration="200" />
<item android:drawable="#drawable/rocket_thrust2" android:duration="200" />
<item android:drawable="#drawable/rocket_thrust3" android:duration="200" />
</animation-list>
Then
AnimationDrawable rocketAnimation;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
rocketAnimation.start();
return true;
}
return super.onTouchEvent(event);
}
Create list of images in drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/loading"
android:oneshot="false" >
<item android:drawable="#drawable/preloader_01" android:duration="50" />
<item android:drawable="#drawable/preloader_02" android:duration="50" />
<item android:drawable="#drawable/preloader_03" android:duration="50" />
<item android:drawable="#drawable/preloader_04" android:duration="50" />
Use ImageView img instead of button and set the list as background in xml, then in code use AnimationDrawable to start the animation
AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();
// Start the animation (looped playback by default).
frameAnimation.start();`
You can animate Alpha, location and just about any property of a button using ObjectAnimators and ValueAnimators.
If you want custom animations such as the ice effect, you'll have to make these yourself.

Designing animation for android application

What is the best way to design and embed an animation into an android app.
(I'm not talking about transitions and activities in/out animations.)
I can think of 2 ways of doing it:
designing the animation with flash or something similar, export png-sequence with transparent bgs and creating an animation from the images in an xml file (How do I write this kind of xml?)
creating a grid of images with all the frames of the animation that I've created
and save it into one image. than using something like background-position in css in order to move the visible area of the image on each frame enter (By Java code, or by xml)
which of this is better/most common? and how do I implement the solution (if there is a better solution - that would be great).
and what programs do you usually use for this kind of task
(the goal is to achieve something that works like the frog in cut the rope or the birds in angry birds for example)
thanks!
I used simple animation in one project... It's on your first point... A sequence of *.png files in /res/drawable, and *.xml like:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="#drawable/s250" android:duration="200" />
<item android:drawable="#drawable/s251" android:duration="200" />
<item android:drawable="#drawable/s252" android:duration="200" />
<item android:drawable="#drawable/s253" android:duration="200" />
<item android:drawable="#drawable/s254" android:duration="200" />
<item android:drawable="#drawable/s255" android:duration="200" />
<item android:drawable="#drawable/s256" android:duration="200" />
<item android:drawable="#drawable/s257" android:duration="200" />
<item android:drawable="#drawable/s258" android:duration="200" />
</animation-list>
... and source...
final ImageView pygalo = (ImageView) findViewById(R.id.imageanimation);
pygalo.setBackgroundResource(R.anim.animation);
final AnimationDrawable pygaloanimation = (AnimationDrawable) pygalo.getBackground();
pygalo.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View vp) {
pygaloanimation.stop();
pygaloanimation.start();
}
});
It is very easy to do...

animation-list not animating initially

I have a checkbox that should look like a green light when checked and a red blinking light when unchecked. To do this I created a selector called connected_selector.xml.
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/green_button" />
<item android:state_checked="false" android:drawable="#drawable/red_button_blinking" />
<item android:drawable="#drawable/red_button_blinking" />
</selector>
The green_button is simply a png and the red_button_blinking is an animation-list of pngs.
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/red_button" android:duration="500" />
<item android:drawable="#drawable/red_button_lit" android:duration="500" />
</animation-list>
The checkbox's background is set to #drawable/connected_selector. If the checkbox is initially unchecked, it doesn't blink, it just shows the #drawable/red_button. However if I check the box and then uncheck it, the checkbox will animate correctly.
How can I make the animation start initially since the checkbox will be initially unchecked? I guess I could try to start the animation manually in code, but I don't think that should be necessary.
Okay, I found an ugly, dirty hack to get around this. Note that I don't have the slightest clue why this happens, just a way around this. It is probably not even a generic way since different devices will have different loading times.
I execute the following workaround in onPostResume() to minimize the necessary delay time.
if(onOffStatus) {
// SLEEP 0.5 SECONDS HERE ...
new Handler().postDelayed(new Runnable() {
public void run() {
switcher.setBackgroundResource(R.drawable.button_state_anim);
// Get the background, which has been compiled to an AnimationDrawable object.
AnimationDrawable frameAnimation = (AnimationDrawable) switcher.getBackground();
// Start the animation (looped playback by default).
frameAnimation.start();
}
}, 500); // Actual required time will probably be dependent on device performance
}
It ain't pretty but I'm going with this until I find something better. Let me know if I overlooked something here.

Problem specific android question regarding frame by frame animation

I'm trying to perform frame by frame animation in android. For this task I created an xml file called "anim.xml" like this:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/square0" android:duration="100" />
<item android:drawable="#drawable/square1" android:duration="100" />
<item android:drawable="#drawable/square2" android:duration="100" />
<item android:drawable="#drawable/square3" android:duration="100" />
<item android:drawable="#drawable/square4" android:duration="100" />
<item android:drawable="#drawable/square5" android:duration="100" />
</animation-list>
Then at a frame layout that I have defined, I tried to set it as background and start it at onCreate like this:
FrameLayout imgView = (FrameLayout)findViewById(R.id.frameLayout1);
imgView.setBackgroundResource(R.drawable.anim);
AnimationDrawable anim = (AnimationDrawable) imgView.getBackground();
anim.start();
What I'm experiencing is the first frame only, but what I'm going for is an animation of squares to be on a loop. Do you have any opinions regarding what I have done wrong ?
Cheers.
To me, Matt's solution seems a little overpowered for this case. You can simply move your call of the start() method to the onWindowFocusChanged() method because at that point the AnimationDrawable is fully attached to the window and can actually be started. Like this:
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
anim.start();
}
Do all the other stuff in your onCreate() method and make the AnimationDrawable a class variable, so you can access it from onWindowFocusChanged() method.
I've experience issues before when trying to get animations to start in the onCreate method. Try repalcing your last line with something like:
imgView.post(new Runnable()
{
#Override
public void run()
{
anim.start();
}
});
This will essentialy make you animation start after onCreate has executed.

Frame-by-frame animations

When I try to code a frame-by-frame animation in Eclipse, It gives me a bug. I found something on the internet that says they screwed up in the sdk tutorial documentation but I cannot help but wonder what android:id="selected" means or what should be put in the quotations instead.
Also, can somebody explain the last part of the frame animation tutorial to me?
http://developer.android.com/guide/topics/resources/animation-resource.html#Frame
Do you put another code in the filename.Java, and if so, where do you put it?
I cannot understand where to put the second code that is not XML. I think I need to know what the code below is and where it should go:
ImageView fileimage = (ImageView) findViewById(R.id.file_image);
fileimage.setBackgroundResource(R.drawable.file_image2);
fileAnimation = (AnimationDrawable)fileimage.getBackground();
fileAnimation.start();
But here is the XML code I used:
<animation-list android:id="selected" android:oneshot="false">
<item android:drawable="#drawable/filename" android:duration="200" />
<item android:drawable="#drawable/filename2" android:duration="200" />
</animation-list>
Should anything be removed or added from that? I don't know what else to do, because I need to start the animation and have the code for that (1st one) but I don't know where it goes, or if I need another code along with it.
This is how I implemented it.
In your main java file you should have something like this.
public class Main extends Activity {
AnimationDrawable mainanimation;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
ImageView mainimage = (ImageView) findViewById(R.id.MainAnim);
mainimage.setBackgroundResource(R.anim.mainanim);
mainanimation = (AnimationDrawable) mainimage.getBackground();
So you set the ImageView in your main.xml layout file to the xml that contains the animation (R.id.MainAnim)
Then in your MainAnim.xml (located in res/anim) file you write
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/image1" android:duration="2000" />
<item android:drawable="#drawable/image2" android:duration="2000" />
</animation-list>
Now image1 and image2 will alternate back and forth at 2 seconds each. Also I didn't use andriod:id="selectable".
To recap you need 3 files. Your Main.java, your main.xml layout file, and your mainanim.xml file located in res/anim. Also your 2 images in the drawable folder.
Hope that clears it up a little.

Categories

Resources