I'm doing my own MyLocationOverlay implementation to bypass extremely slow current position display.
The problem that I've is that I want to make a little animation changing the color of the position marker and the only way I know to redraw is to call invalidate o MapView. But that way I also invalidate all the other overlays. Is there an efficient way if only I want to change color and other overlays don't need redraw?
AFAIK there isn't.
All overlays are drawing to the same object, so to redraw one, it requires clearing everything, and redraw all of them again.
Even if you add another view to the same layout where is MapView, changing that view will result in MapView.invalidate() being called.
Regards.
Related
So there are a few questions about animations not ending when using cancel() on them. You also need to call clearAnimation on the view. Can someone explain why is that? It's also very strange to me, that the View needs to know about what animates it.
You call clear animation to reset the transformation matrix that the view is using to transform its canvas during the animation. The main problem is that old Android animation system is a crap since it relied on animating a "snapshot" of the actual view.
As for the cancel, when you invoke cancel what happens is that you stop the runnable that is applying the steps of your Animation. Of course you cannot be sure in which state your animation is getting stopped
To be clear:
The View Animation Framework , a.k.a "old animation framework", only animates the translations of the view, and not the actual properties. So lets say you animate the view's location on the X dimention: the value of the view's X property remains the same.
In relevance to your question, this means that canceling the animation draws the view back in its original position. So it doesnt matter when did the animation was canceled.
Object animation, introduced in Android 3.0, animates the actual properties. This means that when you cancel the animation, the view remains in its relevant position. So you might not know exactly WHEN was the animation canceled, but you can clearly find out WHERE is it drawn right now.
If you need object animation for older versions of Android, and frankly why go any other way, you can use the 9OldAndroids library.
Mor on the difference between the animation frameworks here.
I am using NineOldAndroids and using setTranslationY and setTranslationX to change the views position (after applying AnimatorProxy). Only problem is when I change the view's position the button is only visually changing its location however I still have to click the original area in order to get the button working properly (instead of the new position).
Can anyone please help me figure this out, would appreciate it very much.
You need to move the view after the animation has completed. As you said, the animation will only change where the view is being drawn.
See this answer: NineOldAndroids, not clickable view after rotation or move
I have a complex frame layout containing several custom views. The main view is a graph.
Overlaying the graph is a custom view which represents a cross hair pointer that the user can drag around the graph to read off detailed information about a particular data point.
The frame layout captures all touch events, calls "hit test" methods on each of it's child views to determine if the touch was on that view then dispatches the touch event to the appropriate view.
When the user touches the cross hair and drags it, I pass the touch event to the cross hair which it uses to update it's position and invalidate itself.
Everything is working except...
All views in the layout are redrawing when I invalidate any of these child views. I know this as I have turned on "show screen updates" in developer options. At no point do I invalidate the containing FrameLayout - or at least, not knowingly.
Certainly, the Activity handling the layout does not invalidate it and I do not have any references to the parent in the child views.
I haven't posted code since a) I don't know if this might be normal behaviour, b) there's a lot of it! and c) if it's not normal behaviour, I don't know which part of the code is problematic. Of course, I'm happy to give anything that might be requested.
My minimum API is 2.3.3 and my target is 4.0. This happens on both of those versions so I suspect my code is the problem but where to start?
Any clues as to what might be going on?
There is no way for View to draw "just itself", since it depends on it's parent (which provides it's clipped and translated Canvas via dispatchDraw method). Invalidation requires whole view tree to be invalidated - this is the answer that you're looking for :)
If you'll check out the source of ViewGroup, you'll find there two important methods: dispatchDraw (which responsible for dispatching draw event down to it's childs) and drawChild (which called by dispatchDraw and let's you specify how childs will be drawn). Note, that there is no check on which View starts invalidation, although there is a RectF that specifies invalidation region. As far as I understand - you need to make sure that your invalidating View (cross) doesn't takes the whole screen, so redrawn will be only that part that it actually takes.
If understand you right, the lines of the cross-hair view cover the whole screen, i.e. one vertical line from top to bottom and one horizontal from left to right.
Now if you change the center of the cross-hair and the other views would not be redrawn, your screen would soon be cluttered with old lines from previous cross-hair positions. You would not want this, so you can be glad that the other views redraw itself too.
If you want, you can specify a 'dirty' rectangle and call invalidate(Rect dirty), which would not redraw Views that are completely outside that rectangle. Though it's up to you in that case, not to change anything outside that rectangle.
try this:
setDrawingCacheEnabled(true);
Enabling drawing cache for view will make view not be redrawn if view not changed
Take a look : Android Invalidate() only single view
May be my answer so simple, but I resolved this problem with help:
this.invalidate()
Run it for each canvas-view, and it will updating one by one (not all at once)
Hi
I am searching for functionality which works like the itemizedOverlay on the mapview, only for Imageview. So that I can add items on specific locations on the image and trigger actions on tap of the item.
I am building an application for Android where you get Floorplans and on this Floorplan the rooms should be marked and clickable to get more information.
Thank you very much for any help or hint in this matter
Use a RelativeLayout or FrameLayout. Both support Z-axis ordering -- later children will appear to float over top of earlier children. Use setOnClickListener() to be notified of taps on the items.
I have a problem with custom ItemizedOverlay on the MapView in Android.
What I've done: Very simple offspring of ItemizedOverlay class that only wraps my own type of items and uses ItemizedOverlay for all the hard work.
What works: Nearly everything - items are drawn properly, I can tap them etc.
The problem: If I drag the map in the view by the map itself, I can scroll it without a problems. But if I try to start moving the map over one of items from my overlay (eg. "dragging map by item"), it doesn't move.
This is really problem, because if I have "a bit more" items, there is no way to drag the map (without un-zooming and grabbing map outside items).
This problem occurs even if I don't handle any events generated by ItemizedOverlay (eg. with onTap() commented out in my overlay).
Any advice would be appreciated.
OK, we solved this issue.
But only solution we found was writing our own version of "ItemizedOverlay" (without inheriting it). Eg. we're drawing our own overlay and we handle "tap events".