Animation is too slow - android

I am working on a game for the Android platform. The layout consist elements which should move without stopping from top to bottom. I decided to use an Handler and I set handler.postDelayed(this, 10).
the animation "step" is 5px (It's actually not px but doesn't matter for the discussion).
The thing is, the animation frequently twitching and isn't smooth. With every call of the handler, I make some simple checks and use setX(), setY() to change the elements position.
What should I do to make the animation smooth? Should I tweak the numbers mention above? Also, I've understood the method setWillNotDraw(boolean b) might be useful - How to use it wisely?
I'd be glad if you could guide me what should I do (Kind of "Do and Don't").
Thank you!

As pskink suggests ViewPropertyAnimator is much friendlier than animating Views yourself. If you want/need to manage it manually, consider View.postOnAnimation instead of Handler.postDelayed to run your update with new animation frames.
Regardless of how you move objects, be wary of how many views you have on the screen. Moving one view can force the entire view hierarchy to redo its layout -- this can definitely kill animation speeds. Try animating a single view in an otherwise empty layout.
Profiling is very helpful for tracking down performance issues.

Related

Choice of drawing and animation technique for an animated music staff

I'm working on an app where I must have on a part of the screen an animated music staff. That's:
5 static lines
A dozen of music notes (each one is basically an oval and a line)
A few additional symbols (clefs)
I must have a precise control of the size of each element, and have to smoothly animate position and alpha of the notes and clefs so the notes are moving right to left (disappearing when on the left of the screen, and appearing when on the right, hence the alpha). I also have to change sometimes the color of the notes.
I think I can't use standard "Animations" class, as it's an endless animation with the speed and the notes depending on real time factors.
So what is/are the best way(s) to do that and to achieve a smooth animation?
Different Views? (VectorDrawables?) Single SurfaceView where I manually draw each shape at each frame? (or TextureView?)
(Note: minimum API is set to 15)
Thank you for helping me choosing the right technique.
So you're wrong about the Animations class being infinite. It doesn't need to be. However EVERYTHING in Android will depend on real life factors- Android is not a RTOS (real time OS), there is no guarantee of execution time.
However, if you absolutely need total control, I would just jump to total control- hook the Choreographer so you get a call every 1/60th of a second, and each frame invalidate your view(s) that need to change and redraw them. If the phone is running slow for some reasons like other apps you may drop a frame or run slightly slower than 1/60th of a second, but this is as close as you can get (and what Animation classes use behind the scenes).
With animators you can animate smoothly around 5 different views on average phone. So in your case (with dozen of notes and so on) it will have around 10fps. So slightly better will be SurfaceView and handdrawing all that you want. Maybe GLSurfaceView worth considering.
In order to test this I recommend you to create some test app first, where will be 10 views flying around, and look at performance.

Is the structure of this code suitable for its purpose and how do I smooth animations in Android?

I am implementing a piano tiles clone for an educational purposes. I've created 5 Views (that's the rows) which extends LinearLayout. Each one of them has 4 childs (that's the 4 tiles).
I am using an Handler for the animation, and change the Y property manually every "tick".
Problem is, the animation is somewhat twitching and not smooth.
I have two questions:
Is that a good design? I know for example about surfaceView as alternative for drawing and animating but that seemed to me a bit complicated for my cause.
How would you animate those tiles? currently I use an Handler (actually I was guided on another thread to use Animation. What do you think the most feet to my case?
Thanks!
I like your grid idea, but you may have to change it if you would like the tiles to be procedurally generated. Also, here is a thread on how to make animations smoother in Java (This can probably apply to Android too):
How can I make a Java Swing animation smoother
Here is one for Android: Moving animation not smooth in android
Also, I feel you are a bit behind, the Piano Tiles phase has disappeared now, much like Flappy bird.

Performance: How to prevent requestLayout() from laying out entire hierarchy

I have a pretty complex android-application. Already flattened view-hierarchies as far as possible, but I still have lags in the application. For example there is a menu with entries that collapse/expand by having their height set by a ValueAnimator. Typically the animation runs with a bit of a lag the first time, and smooth after this first pass.
I noticed that when i call "requestLayout()" on the Menu-Item, Android seems to do a layout-pass and multiple measure-passes through the entire hierarchy.
Since i know that although the Menu-Item(View) changes height, the Menu(View) itself doesn't, is there some way to tell this to the application?
Can i somehow perform this first pass that seems to lag myself so that it occurs after application start-up and not at the first touch-input?
Here's a sketch of the animation I'm doing:
I am not sure why a layout is being triggered in your animation but I am going to answer your question abstractly.
If you are calling requestLayout (either directly or indirectly) in your animation you are doing it WRONG.
requestLayout, for correctness and safety, does a full view traversal on the view hierarchy b/c conceptually changing bounding box of a node in the view hierarchy can result in change in the bounds of any other node. Not always the case but in general it could, thats why requestLayout is a full traversal.
All of this is just another way of saying requestLayout will eat away time from your 16.6 ms frame time slot and make your animation choppy. This is especially bad for deep and complex hierarchies with many RelativeLayouts which internally does two passes per level (thus potentially causing exponential passes on a subtree)
Now, if you want to animate change in dimension use setScale in a hardware layer. And at the end of the animation merrily call requestlayout and also destroy the layer (to free up memory).
Because its a layer, repeatedly calling setScale in your animation results in change of the texture on the GPU and as a result totally bypass the traversal mechanism of the view hierarchy. This should make it buttery smooth.
Your question looks like mine: Only relayout children and not all the tree
First, you can try to avoid complex view hierarchy for your view. If possible, explode views on views that doesn't depend on another one.
When an animation is performed, avoid any layout request. Start your animation with a delay if a layout request is pending.
Use hardware layers for animation if possible (maybe Android use it by default with ValueAnimator)

android - Slide ListView with setX, setPadding, or tween animation?

Without going into too much detail, I want to be able to 'slide' elements in a ListView similar to the 'slide to archive' feature in GMail. I'm fine with the onTouchListener and all that, my question is regarding the slide animation.
The first two things that come to mind are..
view.setPadding(slideOffset, 0, 0, 0);
and..
view.setX(slideOffset);
The former is very buttery, even on the emulator.
The latter is a bit janky on my Galaxy Nexus.
My questions:
* Regardless of what I've tried, what's the correct way to do this?
Why is setX less smooth than setPadding?
Does one approach conform to Android best practices more than the other?
Are tweened translation animations an option? If so, can you provide a brief example to point me in the right direction please?
Edit:
To be clear, I am attaching an image of the effect I am trying to emulate.
I'm pretty sure the setX() is slower because it affects its parents. When changing the X of a view, it calls the onLayout/onMeasure of the parent every time you update the value. That's because the X value of the child may cause other items on the parent to move, therefor the parent needs to redraw itself.
You can test this easily by extending the ViewGroup and writing to the log on those methods. Then, you can use both approaches, padding vs. setX, and see what happens.
Are you trying to animate the item? Or do you want the user to move it like on Gmail? You can use the ObjectAnimator to handle the "X" value of your item. Combined with a "hardware layer" for your item, it will create a smoother experience. You can find more details about how to do that here: http://developer.android.com/guide/topics/graphics/hardware-accel.html
Yeah, if you're targeting higher APIs, ViewPropertyAnimator is probably a great solution. If you have to support lower APIs, my thought process for implementation would be (and I haven't implemented this myself personally, but this should be good for performance) to:
In your touch handler, once you've determined that the user is "sliding", set the View's visibility to INVISIBLE, and store the drawing cache into a separate bitmap (Bitmap bmp = myView.getDrawingCache();)
Draw that bitmap in the same place as the view, and use the Canvas translate methods to shift the position according to the x-position of the user's touch point.
After the user lets go, translate back (preferably smoothly with an animation), recycle the bitmap, and set the view back to VISIBLE.
Check out the 3 devBytes posted on AndroidDev:
https://www.youtube.com/watch?v=8MIfSxgsHIs&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=12
https://www.youtube.com/watch?v=NewCSg2JKLk&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=11
https://www.youtube.com/watch?v=NewCSg2JKLk&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=11
https://www.youtube.com/watch?v=YCHNAi9kJI4&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=4
https://www.youtube.com/watch?v=PeuVuoa13S8&list=PLWz5rJ2EKKc_XOgcRukSoKKjewFJZrKV0&index=3

Smooth animation on top of regular Android View

I currently have an app with a regular layout of buttons and widgets. On top of this I'd like to draw some animated sparks and particles and whatnot going on in response to events, so I've got it in a FrameLayout with another View on top to draw the animations. The problem is I can't work out a way of getting smooth movement out of it. I've tried a few options:
SurfaceView: because of the way it takes over the screen, you can't see anything behind a SurfaceView so the background is fully black.
Override View.onDraw and call invalidate(): this almost works, but invalidate isn't a very reliable way of getting a redraw to happen soon, so the motion is very jerky.
Animation framework: Testing with TranslateAnimation, it seems a bit smoother than using onDraw(), but animations are designed to run for a specific duration and I want to draw indefinitely.
Anybody know any tricks to make one of these work properly, or something completely different?

Categories

Resources