-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recycling marker views #411
Comments
This is an interesting question. But the main difference between the |
The idea is to set a high enough min scale limit so that only a subset of the markers is shown at once. This is still a chance to place many markers on a big enough area. The user will have to scroll, but that is fine. Right now i have a very big area with many markers on it. It is so big that it will never be scaled down enough (scale limit 0.1) to have to show all markers on the screen. The problem is that right now the app crashes when i try to inflate so many marker views at once. |
As you may know, the
To sum up, it's possible and it would be very nice if you could do that so it would be later integrated as plugin for the v3. GL |
i agree with everything Peter said. there are several existing viewport apis already so i'd imagine this wouldn't be too tough to implement. you could also create a custom ViewGroup that managed the marker, which takes a TileView reference, then add it to the view tree, that way you could continue to get updates to the core lib. |
ok i will see how it goes... |
Actually for such a scenario with many many many markers, it probably makes more sense to use raw drawables as markers than views. I just tried that and it is very smooth that way, without making my device burning hot :) ... |
very cool. if you don't mind posting your code (or the basic idea), other users might be able to use the technique |
I'm not sure what you did wrong before, but anyway this is impressive that a device can handle so many markers :) @sdargutev As Mike said, it would be have to have a sample of your before/after code. I could then add it to the wiki. |
Well technically all the markers are contained in one single view. They are just drawables. No need to inflate a view for each marker. The conventional markers layout would still not be able to handle that many marker Views. There are 2 things that would improve performance though:
What i did to solve my problem with the thousands of markers is:
Now even with thousands of markers on the screen it still runs smoothly. Of course, bitmap caching is a must. |
Nice, thank you very much for your detailed answer. We definitely have some improvement to do on the @moagrius in v3 we could indeed invalidate only the current viewport on the |
@sdargutev You'd need to check during each scroll change - running layout passes that often is not feasible. thanks for sharing your code though! @peterLaurence it wouldn't work with Views, invalidating only tell the canvas what area to redraw - if it's not laid out, it's not drawn. the only thing i can think is to draw bitmaps and maintain hit areas with something like a hot spot, but then you lose things like nested views with their own hit areas, etc. maybe we can figure something out as things develop organically |
Would something like this not be possible?
You can keep track of all the markers in a List field in MarkerLayout. |
imagine someone flinging. what markers were in the viewport during the last measure pass are certainly not going to be there when the fling ends. the problem is that you have to calculate what's in the viewport at every scroll change, which is a lot, and how we manage what tiles to show. so it is possible (like i said, we do it with tiles), but if you try to do layout/measure stuff that frequently, everything will blow up. |
@moagrius Is this really a problem? I have tackled GIS matters a little bit in the past, and AFAIK intersection checks with < 10000000 fixed-size objects are very fast, when using appropriate tree structures for lookup. Personally I had good experience with STRtree (found in |
scroll events fire very quickly. yes, it's possible, and no i don't have any concrete metrics on how it'd impact performance. that said, for v3 we're moving to a plugin architecture, so something like that would be perfect as an opt in plugin. |
@mariotaku Do you mean calls to onDraw? Either way, doing lookups in small, localized memory structures is much faster than actually drawing unnecessary objects to screen, especially if objects themselves are non-trivial to draw. I am currently trying to create a small test app, so I might cook up some kind of showcase for you. |
you pinged mariotaku, not moagrius :) no big deal; mariotaku feel free to ignore
No, I mean scroll events. That said, I'm not sure why you're talking about drawing. We're talking about detecting if a marker is in the visible viewport during a scroll or fling event, and if so, laying it out, not drawing it. Markers are much more likely than not to have touch events attached to them; again this means we can't just draw, we have to lay out. Drawing is very different from layout. Drawing is just pixels - layout includes hit areas, elevation, and most importantly: relative positioning and potential reflow, all of which is much more expensive than layout. As I've said a couple times, it's definitely possible to do this, but it's going to take resources that are probably not appropriate to have for all implementations - this is a good candidate for an opt-in, which will be supported in V3. For now, if someone wants to implement it for V2 as a subclass, they're free to do so, but I'm not going to add it to the core of V2. Thanks for your input. |
Sorry, I have been a have been a bit negligent when writing my response :)
I see. I have been reading the code and profiled things a bit. Apparently, the throttling of Of course, there are no reasons, why this can't be extended to TileView child Views.
Wrong. It seems like you are making a common mistake here. The ViewGroup does not have to lay out the Views after scrolling. No one does that. All Android components: ScrollView, RecyclerView, DrawerLayout and boatload of third-party Android libraries do not lay out children after scroll. They only do that once, initially, and shift them using This is why ScrollView, DrawerLayout and many other libraries are designed the way they are designed. There is a single parent, that dispatches scrolling events, and single child, that gets shifted in response to those events. In theory, there can be multiple children (and RecyclerView pulls that off), but calling Offset Views still correctly process input etc. and interact with underlying Views, only their layout position is not affected. When the layout pass finally happens, onLayout positions Views with consideration for their current offsets and offsets are reset. Using this scheme, RecyclerView offsets and moves children around itself without actually laying them out most of time. It only performs the layout pass on them, if something actively causes it (such as changes to contents of it's children). This has been proven to be efficient in practice.
It would much more efficient. You probably don't want to implement full functionality of RecyclerView. But some optimizations are considerably easy to take advantage of. When you feel, that a View can be reused, just move it inside the parent. When it can not be reused, detach and either modify, reuse and reattach or move to scrap. Of course, that optimization could be even more appropriate for the older generation of the library (when tiles also were Views), effectively avoiding creation of throwaway |
@moagrius I hope, that the wall of text above has addressed the point that you have been making: about recycling the Views. Now let's reiterate over the argument, that I have been making (and which you haven't actually addressed):
Calculating, what's in the viewpoint is extremely fast when you use spatial trees to index your objects This is irrespective of specific problem (layout, drawing etc.) That lookup is a very fast thing to do either way. You only need to store coordinates of centre (and sizes, for non-dot objects), and the tree will let you look up, which of them are in the current viewport. The "viewport" still has to be computed, which is already implemented in your code (when drawing tiles). |
i'm not sure how to state this any more clearly: i am declining to implement the feature in question (in this version). as i've said several times so far, i may implement this in v3. i'm not sure where the confusion is - i'm aware of how view recycling works - there is neither new nor novel information in either of your posts - i'm telling you that i'm not going to implement that, at least for the current version (v2). what little time i have for open source work will be directed at v3. your tone is, at times, inappropriate - please post respectfully, or not at all. i would suggest that you edit your comments to show a more civil tone, but ultimately that's up to you. i have the option to edit, delete, or block, but am really reluctant to do so, and have not had to so far, and hope to never have to. thanks you. |
My apologies, I have been confused by the following statement of yours: "We're talking about detecting if a marker is in the visible viewport during a scroll or fling event, and if so, laying it out, not drawing it". You have mentioned laying out Views, and I responded, that it is usually avoided during View recycling. Or did I misunderstood you?
I am not really interested in this specific issue (View recycling) or when the next release is going to be. Your library is nice, and it was very useful to me as is, — thanks a lot for writing it. Because of that, I felt like commenting on this thread and offering you what little advice I could provide. Since there are no chats, mailing lists, forums or other reasonable means of contacting you about TileView, I have left a comment on this issue. It is very unfortunate, that you have taken offence from tone of my posts. I hope, that this won't negatively affect future of this library. |
The TileView crashes when adding a few thousand markers.
Is there anyway to make the marker's views to recycle... Similar to RecyclerView - when a marker is offscreen to reuse it's view for some marker that is onscreen, in order to avoid creating thousands of marker views.
Thank you,
S. Dargutev
The text was updated successfully, but these errors were encountered: