i'm building my interactive map and i find myself really confused:
I have an extend of ItemizedOverlay class which i'm managing the overlays.
when shell i use its populate() function in order to update the overlays in the mapView and when should i use invalidate() or postInvalidate() in order to get the map to update.
i found that sometimes this works, and sometimes the other.
if someone will be kind to explain exactly what each of the function does - i will be thanks full because i couldn't find a decent explanation.
populate() should be used when you want to populate the overlay. If all you want to do is have it redrawn, then you should use invalidate() if you're on the UI thread, and postInvalidate() if you're on another thread. The invalidate methods are applicable to any View, be it a button or a text view or anything. They basically tell Android that something has changed related to the View, like the data being shown or the button's state or colour or whatever. Android will then attempt to redraw the View as soon as possible by calling the View's onDraw() method.
I always use invalidate() and never had a problem with it... (i.e. always refreshes)
Related
I'm working on a project that using custom views created with Android Canvas. And I'm stuck in the next part: How to create custom animations for elements on Android Canvas (the idea), where I cannot use the already-supported-animations. Any idea or example is appreciated! Thanks!
The simplest approach is to hold some state variables in your View. Then you can use ValueAnimator or ObjectAnimator. Former will trigger ValueAnimator.AnimatorUpdateListener where you can modify view state in proper way and then invalidate(), which trigger redrawing. Latter will update view state via setSmth() methods, that you should implement on your view. At the end of these setters you should call invalidate() too. And in your onDraw() you need to draw proper things depending on actual values of state variables
For some reason (that I can develop if you want/need) I have to redraw all the chart periodically. So, I use removeAllSeries then addSeries, plus removeAllViews then addView. It works but the problem is that addView adds the view not by simply refreshing all pixels of the tablet but with a sort of "animation" that puts firstly the View a little bit (2 or 3 pixels) shifted to the right and then it takes the right place. The consequence is that, everytime I redraw my graph, it looks as if there is a "vibration" (it's not fluid).
Do anyone have some issue? Could this undesired "animation" be related to how the addView method is done?
there are three ways:
redrawAll() method. Maybe it is protected, but you can overwrite and
make it public
change the data in series (appendData or resetData). The Graph will
automatically rerender.
removeAllSeries + add new series. No need to call
removeAllViews/addView. Take a look at the GraphViews-Demos project,
there is an example about that.
Cheers
Thank you for your answer ! I actually just simply overrided the ValueDependentColor() method directly in my main activity. The color depends on a timer. So, when I reset data after x seconds the graph rerenders as you said in your "2."
I am creating an android app that is essentially a dashboard with many gauges and indicators on it. I have a Main View which is added in the Main Activity's onCreate() method. Each gauge is a custom View object which is added and initialized in the Main View and drawn in the Main View's onDraw() method. The gauge values are constantly updated by individual threads that are launched in the Main Activity's onCreate() method. When a thread detects the need to change a gauge value, it does so, and then sends a message to the Main View (via a message handler) telling it that the particular gauge needs to be updated (redrawn). I am using invalidate() in the Main View's message handler to refresh the screen. The app runs well, but I am wondering if I am handling the display updates as efficiently as I can. My question is:
When I call invalidate() in the Main View, I assume it is redrawing all the gauge Views, even the ones that have not changed. If so, would it be more efficient to just redraw the View of the gauge that has changed? What is the best way to do that? I have tried calling the individual View's invalidate() and postInvalidate() methods but neither works.
As requested, here is the current state of the onDraw method in the Main View. Eventually there will be a lot more gauges added. The Bezels are static and only change if the device switches configuration (landscape/portrait). The various gauges are instantiated from a Gauge class which extends View:
#Override
protected void onDraw(Canvas canvas) {
speedoBezel.draw(canvas);
tachBezel.draw(canvas);
oilPressBezel.draw(canvas);
oilTempBezel.draw(canvas);
speedoGauge.draw(canvas);
tachGauge.draw(canvas);
oilPressGauge.draw(canvas);
oilTempGauge.draw(canvas);
}
Ok, I have read so many ways to animate in Android I started to mix them up. I would like to rephrase the question:
If I am developing an app with many different objects in the main view that changed frequently but at different intervals, is it better performance wise to:
Add the objects to the main view and use the invalidate(rect) in the main view to update them individually as needed, or
Add each object to a Layout and use invalidate on each view when they require updating.
Important to note that none of the objects overlap
I implement a view by myself, the onDraw method of the view is called repeatedly. This will cause a serious performance problem. The code is so complex that I can't paste here. Anyone can tell me some possible reasons? I haven't touch the view by my finger.
One reason would be that your onDraw method is calling some method that (perhaps indirectly) invalidates the view. Another possibility is something completely unrelated in your program is causing the repaints. Try this experiment: comment out your drawing code and substitute something really simple, such as a simple line draw, just to show that it's working. If the repeated drawing goes away, then it's something in your onDraw code. Just start restoring the current code a bit at a time until the problem reappears and then you can track it down.
If the problem doesn't go away when you try the experiment, then look somewhere else in your code for something (perhaps a worker thread?) that is invalidating your view.
I had the same problem today. I solved it by overriding invalidate() in my View subclass:
#Override
void invalidate() {
super.invalidate();
}
Then I set a breakpoint inside invalidate() and waited for it to hit. When it did, I had a stack trace of the call, and the offending caller. Mystery solved in 2 minutes.
If that doesn't work, trying overriding the other invalidate methods in View.
I wanted to know whether the onDraw method get called without the programmers knowledge. I know that it is called at the first time View is loading and I know it calls when I call invaliade(). But does it calls in any other times?
Yes, whenever a parent view is redrawing itself like if the custom view is within a ScrollView whenever you scroll it...