Calling setBackgroundResource() twice with different frame animations - android

I'm trying to show two different animations. It works fine with the first one. But when I stop the first animation and call setBackgroundResource() second time with my second animation ( and then call start() ) it shows only the first frame.
Is it possible to call setBackgroundResource() twice to set different animations?
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
ImageView imgView= (ImageView) findViewById(R.id.imgView);
imgView.setBackgroundResource(R.anim.animation1);
AnimationDrawable frameAnimation = (AnimationDrawable) imgView
.getBackground();
frameAnimation.setCallback(imgView);
frameAnimation.start();
//Schedule the timer
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
showAnimation2();
}
}, 20000);
}//if hasFocus
}
/**
* Show second animation
*/
public void showAnimation2(){
ImageView imgView= (ImageView) findViewById(R.id.imgView);
AnimationDrawable frameAnimation = (AnimationDrawable) imgView
.getBackground();
// stop first animation
frameAnimation.stop();
imgView.setBackgroundResource(R.anim.animation2);
frameAnimation.setCallback(imgView);
//start second animation
frameAnimation.start();
// here I see the first frame of second animation only
}
I also tried to play with setVisible(...) but it doesn't help

I solved this problem by using two ImageView and switching between them. I use setVisibility() method to hide one view with the first animation and show the second view.

Related

Start Animation from zero visibility to full?

I am using startanimation method to produce a fadein effect on an image. I want the fadein effect to work after few seconds of delay, and before that i don't want the image to be visible. I cannot use the setalpha method as the animation takes the current state of the image. So what should i do here?
imageView= (ImageView)findViewById(R.id.imgfade);
fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fadein);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
imageView.startAnimation(fadeInAnimation );
}
}, 8000);
put imageView.setVisibility(View.VISIBLE); after imageView.startAnimation(fadeInAnimation );

AnimationDrawable animates fast after visibility(gone) followed by visibility(visible)

I have an ImageView that is being used to show some frame animation.
The Duration for these images are all set to 100.
However, the ImageView needs to be hidden sometimes. So the animation is stopped and the ImageView is set to GONE.
When it's time to show the ImageView again, its visibility is set to VISIBLE and the animation is started.
HOWEVER - now the animation is really fast; instead of a duration of 100, it looks like 50. But when I check the duration it still says 100 - but it definitely doesn't look like it.
The code to hide and show the ImageView is as follows:
//hide the animation
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
if (frameAnim.isRunning() == true)
{
frameAnim.stop();
}
frameAnim.setVisible(false, false);
animImgView.setVisibility(View.GONE);
//show animation
animImgView.setVisibility(View.VISIBLE);
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(true, true);
frameAnim.start();
What could be the trouble ?
After some experimentation I found that the best way is to simply implement:
//hide the animation
animImgView.setVisibility(View.GONE);
//show animation
animImgView.setVisibility(View.VISIBLE);
this will preserve the animation speed. My original intent with the animation stop/start was to ensure the CPU wasn't doing more than was needed.
To achieve the original goal of not just changing visibility, but also stopping the animation when invisible:
//hide the animation
animImgView.setVisibility(View.GONE);
//stop animation
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
if (frameAnim.isRunning() == true)
{
frameAnim.stop();
}
frameAnim.setVisible(false, false);
//start animation
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(true, true);
frameAnim.start();
//show animation
animImgView.setVisibility(View.VISIBLE);
The difference here is that starting and stopping the animation occurs while the ImageView is invisible/gone. For some reason, starting and stopping the animation when it is visible causes the timing issues.
Source: I ran into this problem myself and fixed it using this technique.
Struggling with Android I found next solution:
don't use start() and stop() methods.
Use setVisible(true, true) to start animation:
animImgView.setVisibility(View.VISIBLE);
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(true, true);
and setVisible(false, true) to stop it (note the bold true):
final AnimationDrawable frameAnim = (AnimationDrawable) animImgView.getBackground();
frameAnim.setVisible(false, true);
animImgView.setVisibility(View.GONE);

android frame by frame animation - differences with these two codes

I would like to animate some images.
Could someone tell me why this first piece of code does not work, but the second one does work ?
And if I have to use the second one, how do I STOP the animation into the runnable ?
EDIT : the first code works on android 4.x, but not on 2.2 (both simulator and device)
code 1 (into "onCreate()" ):
ImageView boule = (ImageView)findViewById(R.id.boule);
boule.setImageBitmap(null);
boule.setBackgroundResource(R.anim.anime);
AnimationDrawable animation = (AnimationDrawable)boule.getBackground();
animation.start();
// does not animate anything...
code 2 (also into "onCreate()" ) :
ImageView boule = (ImageView)findViewById(R.id.boule);
boule.setImageBitmap(null);
boule.setBackgroundResource( R.anim.anime );
final AnimationDrawable animation = (AnimationDrawable) boule.getBackground();
boule.post(new Runnable() {
public void run() {
if ( animation != null ) animation.start();
}
});
// OK, it works, but how do I stop this ?
You can try this.. this code works properly
BitmapDrawable frame1 = (BitmapDrawable)getResources().getDrawable(R.drawable.jth);
BitmapDrawable frame2 = (BitmapDrawable)getResources().getDrawable(R.drawable.jthj);
int duration = 10;
final AnimationDrawable ad = new AnimationDrawable();
ad.setOneShot(false);
ad.addFrame(frame1, duration);
ad.addFrame(frame2, duration);
iv.setBackgroundDrawable(ad);
ad.setVisible(true, true);
Put ad.start(); in button onClickListener and ad.stop(); for stop animantion

ImageView will not trigger after click on the image, but will trigger after click on TextView

I have an ImageView in my xml file, i want to rotate the image when it's clicked.
I use the following code to archive this:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
img = (ImageView) findViewById(R.id.imageView1);
Animation an = new RotateAnimation(0.0f, 360.0f, img.getWidth() / 2,
img.getHeight() / 2);
an.reset();
// Set the animation's parameters
an.setDuration(1000); // duration in ms
an.setRepeatCount(0); // -1 = infinite repeated
an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
//an.start();
img.setAnimation(an);
}
return true;
}
But te problem is, when i press on the image nothing happens, the image won't turn. But if i click on the image and after that click on a TextView, the image does rotate.
This is so random.
What am i doing wrong? How can i fix this?
Thanks.
Well, it seems that you are calling the onTouchEvent function for your whole activity. Thus, any touch action not "consumed" by a view inside your activity window will trigger this function. So it would be logical that you touching somewhere on your activity such as your TextView would trigger this image rotation thing.
My best guess seeing your code would be this: it would be best to implement a touch/click event listener for your ImageView itself, not for your whole Activity. Here is a code snippet that does this:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
/*YOUR CUSTOM CODE AT ACTIVITY CREATION HERE*/
/*here we implement a click listener for your ImageView*/
final ImageView img = (ImageView)findViewById(R.id.imageView1);
img.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Animation an = new RotateAnimation(0.0f, 360.0f, img.getWidth() / 2, img.getHeight() / 2);
an.reset();
/* Set the animation's parameters*/
an.setDuration(1000); // duration in ms
an.setRepeatCount(0); // -1 = infinite repeated
an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
//an.start();
img.setAnimation(an);
img.invalidate(); //IMPORTANT: force image refresh
}
});
}
I would second the recommendation by epichoms (using an OnClickListener). Also, make sure your ImageView can receive clicks:
final ImageView img = (ImageView)findViewById(R.id.imageView1);
img.setClickable(true);
img.setFocusable(true);
img.setOnClickListener(new View.OnClickListener(){
...
You can set these values in your XML layout as well:
android:clickable="true"
android:focusable="true"

Starting Frame-By-Frame Animation

I have a basic question about starting a frame-by-frame animation.
When I call the AnimationDrawable.start() method from my code directly, it doesn't seem to work.
public void onCreate(Bundle savedInstanceState) {
...
mAnimation.start();
...
}
But if I put this line inside the onClick() callback method of a button, pressing the buton starts the animation.
Why doesn't this line work in the code?
Thanks!
Code:
public class MyAnimation extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
AnimationDrawable mframeAnimation = null;
super.onCreate(savedInstanceState);
setContentView(R.layout.my_animation);
ImageView img = (ImageView) findViewById(R.id.imgMain);
BitmapDrawable frame1 = (BitmapDrawable) getResources().getDrawable(
R.drawable.splash1);
BitmapDrawable frame2 = (BitmapDrawable) getResources().getDrawable(
R.drawable.splash2);
int reasonableDuration = 250;
mframeAnimation = new AnimationDrawable();
mframeAnimation.setOneShot(false);
mframeAnimation.addFrame(frame1, reasonableDuration);
mframeAnimation.addFrame(frame2, reasonableDuration);
img.setBackgroundDrawable(mframeAnimation);
mframeAnimation.setVisible(true, true);
//If this line is inside onClick(...) method of a button, animation works!!
mframeAnimation.start();
}
}
It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. If you want to play the animation immediately, without requiring interaction, then you might want to call it from the onWindowFocusChanged() method in your Activity, which will get called when Android brings your window into focus.
Very end of the page
http://developer.android.com/guide/topics/graphics/2d-graphics.html
ImageView img = (ImageView)findViewById(R.id.some layout);
AnimationDrawable frameAnimation = (AnimationDrawable)img.getDrawable();
frameAnimation.setCallback(img);
frameAnimation.setVisible(true, true);
frameAnimation.start();
and to add animation you can do something like
<animation-list android:id="#+id/my_animation" android:oneshot="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/frame1" android:duration="150" />
<item android:drawable="#drawable/frame2" android:duration="150" />
</animation-list>
Use a Runnable to insert the start() message to message queue, just add this LOC to replace your mFrameAnimation.start();
img.post(new Starter());
Helper inner class:
class Starter implements Runnable {
public void run() {
mFrameAnimation.start();
}
}
to play an animation just in onCreate(...) add:
ImageView mImageView=(ImageView) findViewById(R.id.image);
mImageView.setBackgroundResource(R.anim.film);
mFrameAnimation = (AnimationDrawable) mImageView.getBackground();
mImageView.post(new Runnable(){
public void run(){
mFrameAnimation.start();
}
});

Categories

Resources