Flash when changing the screen with fading out effect - android

I am trying to achieve a simple fadeIn and fadeOut effect when transitioning between screens. I have set a stage but when designing my app I did not use any actors. Therefore, I have put it a black screen as an actor and then I set the alpha to 0 on show(). When fading out what I do is I fade in the black image using
stage.addAction(Actions.sequence(Actions.fadeIn(1), Actions.run(new Runnable() {
#Override
public void run() {
game.setScreen(new gameScreen(game));
This works, however there is a small problem, right at the end of the fade there is a small flash for a millisecond which shows the previous screen before it switches so the transition is not smooth, the black image is removed before switching screens. How can I fix this?

your problem is that stage.clear() and stage.dispose() is being called before rest of your app is being rendered last time.
The solution is to override dispose() Screen method and manually set some flag shouldBeRendered to false and then dispose your stage.
boolean shouldBeRendered = true;
...
public void render(float delta)
{
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(shouldBeRendered)
{
//here you render all
}
...
}
...
#Override
public void dispose()
{
shouldBeRendered = false;
stage.clear();
stage.dispose();
}
You can add some System.out.println() to both render and dispose methods to see the flow of Screen circle of life

Related

AlphaAnimation Rotates Framelayout in KitKat

I have a simple activity that spins an arrow to a random angle, and when the arrow stops spinning it flashes. The flashing effect is an alpha animation applied to an imageview of a lit version of the arrow.
It works just fine in Lollipop and above, but in KitKat when the alpha animation is applied it negates the setFillAfter of the completed rotation animation and the arrows instantly change to pointing straight up (0 degrees)
public void Spin2 ()
{
spinning = true;
degreeEnd = rnd.nextInt(360);
RotateAnimation spinIt = new RotateAnimation(0,3600+degreeEnd, RotateAnimation.RELATIVE_TO_SELF,0.5f,RotateAnimation.RELATIVE_TO_SELF,0.5f);
spinIt.setDuration(6000);
spinIt.setFillAfter(true);
spinIt.setInterpolator(new DecelerateInterpolator());
spinIt.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
arrowLit.setVisibility(View.VISIBLE);
animBlink = new AlphaAnimation(1,0);
animBlink.setDuration(500);
animBlink.setInterpolator(new AccelerateInterpolator() );
animBlink.setRepeatCount(Animation.INFINITE);
// in KitKat this animation seems to reset the rotation..
arrowLit.startAnimation(animBlink);
spinning = false;
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
theSpinner.startAnimation(spinIt);
}
Interestingly, when you start the spinning again it flicks back to where it should be (degreeEnd) and starts the spin from there.
It is like it is temporarily overriding the setFillAfter of the rotation. I have tried various combinations of setFillBefore etc on the animations. Also, if I set the blinking animation to a finite number (eg 4) it will stop and stay at the zero - it won't correct until i re-spin.
Again, this works just fine in API 20 and up.
Thanks for any help
Andy
It seems to be something to do with the Frame Layout. Once it was out of the equation it works fine on KitKat.

Any tips for reducing lag when running multiple animations at the same time?

Once my app reaches ~4+ animations running concurrently, the animations start to lag a little. Are there any ways I could fix/optimize that? I am using ObjectAnimator and ValueAnimator.
So, if the views are not having to redraw themselves during the animations, you can enable hardware layers during the duration of the animations. For instance:
final View myView = // your view
Animator animator = ObjectAnimator.ofFloat(myView, View.ALPHA, 0f, 1f);
animator.setDuration(1000);
animator.addAnimatorListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
myView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
#Override
public void onAnimationCancel(Animator animator) {
myView.setLayerType(View.LAYER_TYPE_NONE, null);
}
#Override
public void onAnimationEnd(Animator animator) {
// See http://stackoverflow.com/a/19615205/321697
myView.post(new Runnable() {
#Override
public void run() {
myView.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
}
}
animator.start();
I'd suggest breaking that listener implementation out into a separate class, but the general idea is that you want to put the view into a hardware backed layer as soon as the animation starts (animation properties such as translation, rotation, scale, and alpha are incredibly cheap when backed by a hardware layer) and then clear the layer once the animation is complete.
In the onAnimationEnd callback, you'll notice a link to another answer where there's a bug with 4.0.x if you set the layer type to none in the onAnimationEnd callback. If you're only supporting 4.1 and above, the runnable indirection shouldn't be necessary.
EDIT: If you're animating a color transition, you probably don't want to do the above, as changing the color of the view will require it to be redrawn, causing it to rebuild the hardware layer on each frame.
If you have not used ViewPropertyAnimator, you better do. I moved and flipped(changed picture) 52 imageViews (one deck of playing cards) smoothly.
Here's an example on how to use ViewPropertyAnimator.

Animate sprites using drawableAnmiation

I have a design question so I don't start off on the wrong way. I am planning to have a sprite where it animates moving and I want to move this sprite around (changing position once every second).
I noticed that some tutorial talk about having a game loop,, onDraw on Canvas, bitmap ..etc
However, I am thinking of using drawableAnimation where I specify the set of images to load in xml and call start on it. Then I can just draw at the position required every second ( no loop, it is more like listener that gets called every sec from different process).
Do you forsee an issue? Any problem with above method
Thank you
Drawable Animation requires a fixed frame animation. Think of it like a flip book. The drawable would have to be the entire size of your canvas and your sprite would have to be prerendered on top of some transparent background to achieve your affect. It also would require a large amount of texture memory depending on the size and number of frames.
The "game loop" as you stated is sort of what Android already provides in a way. Inside of the standard canvas setup you have your "main Thread". So with an entity like a Handler you could tick frames if you like.
i.e.
Handler handler;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
handler = new Handler();
handler.post(new Runnable() {
public void run() {
boolean isLastFrame = drawFrame();
if (!isLastFrame) {
handler.postDelayed(this, ONE_SECOND_MILLIS);
}
}
});
This is not the greatest really either.
You could also encapsulate your sprite inside a View or own custom Drawable and inside your onDraw() method, you would update your canvas.
public void onDraw(Canvas canvas) {
// clear canvas
mPaint.setColor(Color.WHITE);
canvas.drawPaint(mPaint);
// Draw current
mPaint.setColor(Color.BLACK);
canvas.drawRect(rect, mPaint);
}
public void moveSprite() {
rect.offset(3, 3);
invalidate();
}
You could also, if using a View, use an ObjectAnimator to translate the View from position (x1, y1) to (x2, y2).
public void moveTo() {
if (!moveNeeded) {
return;
}
View view = getMyView();
view.animate().x(1).y(1).setListener(new Animator.AnimatorListener() {
public void onAnimationCancel(Animator a) { }
public void onAnimationStart(Animator a) {
}
public void onAnimationEnd(Animator a) {
moveTo();
}
public void onAnimationRepeat(Animator a) {
}
});
}

Animation flickering in ANDROID

I am trying to implement something relatively simple in ADNROID. I have a bunch of Drawables stored in a list. I want to create an effect where the drawables are displayed on top of each other, one by one, using a fade-in effect.
I have had partial success with the code below. It actually works flawlessly on my phone (Nexus S), but it shows flickering on my tablet (ASUS TF101). This is probably due to the fact that the tablet has a faster CPU.
Here is my setup: I have stored all the Drawables in the drawables list. I have also defined two images in my layout, one on top of the other: imageViewForeground and imageViewBackground.
The idea is to set the background image first, then start an animation where the foreground image starts from alpha-0 and goes to alpha-1. Then replace the background with the new foreground image, choose a new foreground (i.e. the next drawable) and loop forever.
The counter object is a simple wrapper for an int counter.
Here is my code:
final Animation fadeInAnimation = new AlphaAnimation(0f, 1f);
fadeInAnimation.setDuration(2000);
fadeInAnimation.setStartOffset(3000);
fadeInAnimation.setFillBefore(false);
fadeInAnimation.setFillAfter(true);
fadeInAnimation.setRepeatCount(Animation.INFINITE);
fadeInAnimation.setRepeatMode(Animation.RESTART);
fadeInAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
imageViewForeground.setImageDrawable(drawables.get(counter.value()));
Log.d(TAG, "onAnimationStart");
}
#Override
public void onAnimationEnd(Animation animation) {
Log.d(TAG, "onAnimationEnd");
}
#Override
public void onAnimationRepeat(Animation animation) {
imageViewBackground.setImageDrawable(drawables.get(counter.value()));
counter.increase();
// the problem appears in this line,
// where the foreground becomes visible for a very small period,
// causing the flickering
imageViewForeground.setImageDrawable(drawables.get(counter.value()));
}
});
imageViewForeground.startAnimation(fadeInAnimation);
Any ideas how I can overcome this flickering problem?

Android image moving animation problem

i used following code to animate a image it works fine but while animating the image looks little jumping rather than smooth moving.(It looks like moving but not quite smooth. it stops a while in between) Can Any one find the problem in code?
class AnimationLoop implements Runnable
{
public void run()
{
while(true)
{
while(running)
{
try
{
Thread.sleep(30);
}
catch(InterruptedException ex) {}
}
}
counter+=1;
updatePosition(0);
main.postInvalidate(); //main is type panel
}
private synchronized void updatePosition(int index) {
mYPositions[index]-=2; // animate from bottom to top
mXPositions[index]-=2;
}
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(balloonSet.get(0), mXPositions[0], mYPositions[0],null);
}
The smoothness of your animation will depend on the change in coordinates and the time it stays at a single coordinate. If you want to move the animation at same speed but a little smooother, then reduce the time and unit change by same ratio.
For example: Your case reduce by 50%. That will make x and y position to be deducted by 1 and the sleep time will be 15ms.
This might help how to animate bitmaps

Categories

Resources