Android: self written RotationAnimation for speedometer - performance? - android

I'm a step further with my speedometer, but I'm not that satisfied with my "solution".
I created my own View for displaying my Speedometer. The View extends ImageView and displays the speedometer (without the needle). When the speed is going to be updated, the needle will rotate to the current angle and the View invalidates. Now my problem is, that the needle kind of "jumps" (p.e. from 50km/h to 100km/h). Now I'd like to draw a smooth Animation over that.
A RotationAnimation rotates my whole speedometer, this is why I decided to write a new Thread which animates the needle with 30FPS and therefore calls invalidate() 30times per second. That works, but I allways have that additional Thread in the Background. When I later have more instruments than the speedometer, there are lots more Threads. Now my first Question: How performant is my solution? How many threads could be handled per Application?
My second idea is to use a SurfaceView for the needle, where I could use a RotationAnimation. But I'm not sure, whether it is possible, to show the current speed on a digital Display while the needle rotates. (p.e.: the needle animates from 50km/h to 100km/h, so it is important, that the speed on the digital display is always the same, the needle points at, and not that it always shows 50, until the needle reaches the 100, and then the digital display jumps instantly to 100).
I hope you could help me with some nice tips.
Help would be greatly appreceated

you could try to implement the Observer/Observable pattern in combination with a presenter. your "current speed" caluclation logic would update the "view-model" object which implements the observable pattern and is registered on the presenter(observer). now with every update the presenter is notified and it invalidates/repaints your view. On top you could add a"cooldown" to the presenter which prevents updates to be propagated more often than x times per second.
that would scale to whatever amount of signals and pipe all logic through your presenter class.

Related

Animation ist only smooth when ontouchevent is called

i'm making my first 2d sidescroller game using a surfaceview and a canvas to draw things on (a lot of primitives put in different path objects).
my game loop uses fixed timesteps with linear interpolation. i don't create any objects during the game. i've been improving my code for 3 weeks now, but my animation is still not all the time smooth. it's ok, but every few seconds there are a lot of little hicks for about 1 or 2 seconds.
what i recognized is when i move my player (this means touching the screen), the little hicks disappear for as long as i touch the screen and move my player.
this means as long as ontouchevent of the surfaceview is called, the animation is smooth.
i dont understand this and i want a smooth animation. can somebody help me?
This sounds like a known issue on certain devices. See e.g.:
Android SurfaceView slows if no touch events occur
Animation glitches while rendering on SurfaceView
Android thread performance/priority on Galaxy Note 2 when screen is touched/released
The problem is that the system is aggressively reducing clock speeds to save power when it doesn't detect interaction with the user. (Qualcomm in particular seems fond of this.) The workaround is to drop frames when necessary. See this article on game loops, and a Choreographer-based trick demonstrated in Grafika's "record GL app" activity (in doFrame()).

How to deal with overlapping RotateAnimation-s on Android?

I am using RotateAnimation to animate pointing arrow that updates its position when of user updates destination point or current device position changes. I'm using interpolator.accelerate_decelerate to make animation look more smooth and "physical".
Everything goes fine until another update arrives when current animation is still processing, for example, when user changes destination while pointing arrow is still rotating. When such happens, the arrow makes a sharp bounce which looks ugly, and I'm trying to avoid this. I tried to implement a queue to make every next animation wait until previous ends and it looks nice, but behavior became quite illogical.
So my questions are following:
1) is there some way to make animated transitions more smooth in the cases when animations start one by one and overlap each other?
2) is there a way to stop animation that is currently processing and get intermediate position of an object?--if I decide to stop animation before its end and use current position as starting point for next animation.
ok so the easiest is to create a custom Animation similar to RotateAnimation and saving the current rotation angle in applyTransformation, this angle can be then used as a start angle for next Animation thus avoiding the "jumps"
A custom class extending ImageView that performs animation based on angular movement of dipole in magnetic field:
https://stackoverflow.com/a/22738030/3459206

Updating SurfaceView with multiple dirty rectangles

In the project I am working on I decided to use SurfaceView instead of a custom double buffered medium. It provides everything I need and it's already double buffered.
The problem is that it wont let me specify multiple dirty rectangles to redraw.
SurfaceView.lockCanvas(Rect) only allows single rectangle and without parameter it's pretty expensive to redraw whole thing. Another solution to call lockCanvas(Rect) for each Rect causes eye-bleeding blinking in the screen, obviously.
Do you have any solution giving the opportunity staying inside Android API field, if not do you have any external alternatives I can use?
If you know the dirty areas before you need to call lockCanvas (sounds like you might), you could calculate a "super rectangle" that locks an area that contains all of your rectangle. For example if your rectangles are (using l,r,t,b coordinates) [0,10,0,20] and [15,30,10,35], your super rectangle would be [0,30,0,35].

Help me optimize this graph animation

I need some help with this simple animation on my Android phone. I'm a newbie with animation and graphics.
I'm graphing accelerometer data as a sliding time series window. As new accelerometer data is read, its data is plotted on the right, pushing previous data to the left, as shown below:
My program is running pretty smoothly, but I would like some help optimizing the animation. Here are my main concerns:
My current implementation reads all the accelerometer data in one thread and keeps the data in a fixed-size FIFO queue to capture the width of the time series window. I then use Timer.scheduleAtFixedRate() to plot out the entire contents of the queue so that the whole graph is re-drawn every 50 milliseconds. Can I improve upon this? Do I really need to re-draw the graph so often like this? In another similar program I've seen, each pixel column is copied to one pixel to the left, rippling down the graph; the newest data's column is drawn on the far-right pixel column. Is this better?
I redraw the legend (in the upper left) in the drawing thread that runs the draw function every 50 milliseconds. Is there any way to "keep" that legend in place instead of having to constantly re-draw it?
Any other help would be appreciated. I have heard of optimizations like double-buffering but am clueless if that would help me.
If the legend and the cross hairs only need to be drawn once, then you should place it into a buffer bitmap. For your graph line maybe try using the Path object to plot the lines. When it gets time to draw the lines just drawLine to the appropriate point and then translate the canvas left appropriately.If

How to animate in Android Canvas?

I want to draw something at about 30 frames per seconds on Android Canvas or other convenient object for this purpose. In my application different graphic objects are drawn and if any of the graphic object is touched, the graphic object changes its shape. I looked at the
onDraw(Canvas canvas) callback of View subclass but calling invalidate() does not help here: first I cannot control the frame rate and second if the objects are moving too fast, the motion appears jerky.
I personally dislike Android's built-in Animation classes, so I tend to do all animations with Canvas by hand. I have found the most luck with creating a list of the images you want to use in your animation and then an int variable to store the current "frame" you are on. To advance the frame, I create a thread that sleeps for, say, 30 ms and then update the frame variable accordingly. Then in whatever update handler you are using, you can just create a switch statement or something of the like, and draw the respective frame.
It may seem like a lot of work, but it really isn't. Shove it all into a class and you will love yourself for many animations to come.

Categories

Resources