Jon (00:10.25) Welcome back to Gone Mobile. Here again with me, Alan. Today, how's the weather up your way? It's pretty icy and was snowy, but no longer. Allan Ritchie (00:17.892) Yeah, you shared it from west of me. It's come all here, all in a ton. So it's pretty miserable looking outside here. Jon (00:25.622) You know, everybody asks me in the winter, like, you know, if I, if it's all snow here, right? Cause it's like, oh, you're in Canada. It must be like snowy, right? Um, one of my party tricks actually that I've used for many years. And it probably still applies to you too, up even where you are. Like if you draw on a map, a line, like across, you know, where, where we are. North and South, and you look at all of the parts of the U S that are actually like farther North than us, maybe me is more so than you. There's a lot, there's like entire states that are like north of us, right? So everyone's like, oh, you're in Canada. You're so far north. Oh no, it's actually kind of a mix of snow and rain and it kind of is just terrible. Allan Ritchie (01:05.16) You're not that far north of me though. You're four hours west? Southwest, yeah, okay. Jon (01:07.346) I'm far south of you. I'm, I'm... ..southwest. Anyway, today we're what better thing to do when the weather's bad than talk about things like lists of things in mobile apps, everybody's favorite topic, right? Allan Ritchie (01:24.62) Oh yes, I'm sure people are going to want to hear this one for sure. Jon (01:28.738) Before we dive into that though, I did want to address a listener question that we had come in on a previous episode. So this one comes from Johnny. Thanks, Johnny, for listening. And the question is, I have a technical question that's been bugging me since the first minutes I started using MAUI. Why is the CLI command different from console or ASP.NET apps? Also other UI frameworks like Avalonia allow developers to call.NET run to run the application with Maui, the command is.NET build-t run. So the target is run. Can you shed some light on the topic? Do you, Alan, do you have any guesses? You probably know this. No? Allan Ritchie (02:05.468) No, I don't... No, actually I don't. I don't use the CLI ever other than CI. So this is all you. Jon (02:13.486) Okay, so good opportunity for trivia then. The reason, Johnny, that this is the case is there's a little bit of history involved and basically in early days of Maui in.NET 6, when you run.NET run the command, NET run kind of implicitly calls like a.NET build if you don't specify it not to, right? Which implicitly calls a.NET restore if you don't tell that to, not to call that implicitly as well. However, when we're building Maui apps, there's like a little bit more information, even from the command line, that really you probably wanna specify in the app. Like for a Maui project that's multi-targeted, that targets all the different platforms, right? What does.NET Run mean, kind of, right? That was the first question when we started looking at this. So.NET Run, I wanna tell it, hey, I wanna run the iOS target framework of this project, or I wanna run the Android one. I might want to tell it what target device or emulator or simulator that I want to run it on. So there's a few different things that you could specify. Now, early days.NET Run didn't allow you to pass MS build arguments into it. So if.NET Run was going to implicitly call.NET Build, it would just call.NET Build, it wouldn't know what platform to build for, it wouldn't know what target device to launch on, et cetera. And so when we first did this, we kind of said, okay, well, The closest thing that we can kind of do is.NET build with a target of run, and that will allow you to specify some additional information for those things. I think since in.NET 7, or maybe it was only in 8, you can now pass MS build arguments down to.NET build via.NET run. But I think there was still some, I think there was some loose ends still that we had to tidy up for being able to like specify things properly. And it was kind of a little bit. Allan Ritchie (03:55.824) Net7, it worked for sure. Jon (04:04.79) the way that you had to pass those extra arguments in was a little bit strange too. So the simple answer is that whole kind of chaining of implicit steps before when you call.NET Run. And so we ended up saying, hey, let's use.NET Target Run for now. Hopefully, at some point, and maybe we'll look at this for Net9, we'll actually try and... And implement things so they're done at run. I know one thing I've wanted to do is make things more consistent to across the different platforms, right? So if I'm. Doing a dot net run and I'm targeting iOS there's a different MS build property that you have to pass in for like which emulator or device you want to build with an Android is like a different property. That you have to pass as well, and so you know at some point in the future, I think we'll get some consistency there and we'll make that work but. That is the reason for that particular question. So thanks again for reaching out and you know, anyone else, if you have a question, let us know. We'll try and answer things on future episodes and it's kind of fun having some of these trivia items and getting to talk through them a little bit on the air. Allan Ritchie (05:06.788) Here's a pressing question. Why not run them all? Jon (05:10.942) Well, you might want to run them all, but you also might want that nice, tidy, fast dev loop because you're iterating on one platform at the particular time too. Allan Ritchie (05:20.848) I know when people do hot reload, they tend to, they want to tend to run them both at the same time because you want to have that consistent experience. So that's one I hear about frequently. Jon (05:27.682) You want to see it everywhere, yeah. Yeah, certainly not out of the question. I mean, you could in theory do that too, probably in the future, so. Anyway, onto our main topic, lists, list of things. What do you know about dealing with lists in your app? Allan Ritchie (05:36.904) There we go. Feature request. Allan Ritchie (05:45.5) Well, it can sometimes be a performance issue. I'm finding one right now with some dynamic sizing. It's really only the funny part is, is it's really only showing up on, on one of the big tablet phones. That's what I like to call the big iPhone pro max. That's bigger than your hand. Jon (06:03.05) It's so big that it can't even handle the list of things. Allan Ritchie (06:06.548) Exactly. It's such a big screen. I know there's cases where I can find where it can be a little bit difficult with collections, but basically everywhere in your app you need these things, right? Collection views, list views, whatever other kind of lists there are. Jon (06:23.954) Yeah. And that has been a challenge. Uh, and you know, I, I don't, I'm, I'm speak of my own words on this podcast, right? And I'm not, you know, putting on my, my Microsoft hat for this podcast. And, and I will, but I will say like, yeah, this is a challenging thing in apps. And it's something that we hear a ton of feedback about with Maui that collection view is hard. It doesn't, you know, there's bugs. Um, It doesn't work properly in every case that you want to use it in. And, um, so it's certainly has been something that we've paid a lot of more attention to recently and continue to. But I think it'd be kind of interesting too, to talk a little bit about like the history of some of this and, and that also helps maybe explain a little bit of kind of how we landed, where we're at today with things, um, because obviously, you know, with Xamarin forms. We did things a certain way at a certain time in history when mobile platforms had a certain set of capabilities available to us, right? So if we start kind of looking back at the history, I remember writing another fun trivia fact here, I actually have written, well co-authored anyway, a book. And one of the chapters that I wrote in that book, it was I think called like professional. mono for Android programming or something like back in the novell days, right when it was mono for Android and mono touch. Allan Ritchie (07:45.176) If so long ago you don't even remember the name of your book. Jon (07:47.566) I don't, there's one somewhere in my basement still, a copy that I could, I should go look up. But the chapter that I wrote, or one of the chapters I wrote in it was about dealing with lists of things on Android. And so this was in like the, the device I had at the time was a Samsung Galaxy S. Not a, not an S two or three or four or five or six or 24, just the S, right? So this is way back when. Allan Ritchie (08:06.381) first gen. Jon (08:13.778) And at that point in time, there was a list view, list control, list view control. I don't even remember the name of the thing. Okay. No, no, we're, you know, hey, like spoiler alerts, all these episodes, we'll get to the recycler view. We're not there yet. The list view was the thing, and you had to create your own adapter for this list view. Allan Ritchie (08:18.376) There was a list view. Yeah, it wasn't RecyclerView then. That was before that. Allan Ritchie (08:29.054) Hehehe Jon (08:36.958) And the adapter was actually pretty similar in concept, I think, to how Apple started theirs with iOS, right? So on iOS, they had a UI table view. That was their sort of list of, of data. And. Allan Ritchie (08:49.652) But they did have an adapter plug-in, more or less. What did they call it? Jon (08:53.794) The, you mean for monotouch? Are you thinking? Allan Ritchie (08:56.4) No, for the... they kind of had an adapter pattern as well. You had to give the... Yeah, that's what it was. Jon (08:59.922) Oh yeah, yeah. Like a data source. There's a few different versions because they have like ones that combine both the data source and the delegate into one as well. So you can kind of, there's a few different ways you could slice it, but the result is the same. And on the UI table view, they basically, you fill out an adapter and they kind of ask you like, okay, well how many sections are in this table view? And you have to provide that answer, right? So sometimes you might say, I just have one section. I have a ton of rows, but just one section. Uh, then you have to also say how many rows are in a given section. So they'll tell you, Hey, for section zero, how many rows are in there? Uh, and then you can kind of keep filling that out. If you have multiple groups or sections, you know, you'd obviously return the right information there. And then I think, uh, the other big part of that was you would have to give them back a UI table view cell that you would, that would contain like your view of, of the information, right? And the way that iOS did this, and I don't, I kind of often say like Apple invented some of these things, but I don't know if that's truly the case, but certainly they, the pattern they used became very popular on other platforms, which was this whole concept of recycling, right? So the idea being, I have a phone, I have a screen, it maybe can show, let's say it can show 10 items at any given time on the screen. You might have items of different sizes and stuff, and that number could fluctuate up or down. But the idea was that they would basically call you kind of just before, like as a user scrolling through the list, they'll call your get, you know, table view cell method or whatever the thing's name, get cell, and they'll say, here's like the index of the row I want for this given section. Give me the view representation back of this. And so you would return that. instance or you'd get so here's the thing you would get an instance if you didn't have any uh you know sitting there to give it and the way that you would get that instance you would first ask it hey can you dequeue a reusable cell for me and you would manage you would register these reusable cells by a particular identifier that you picked because you might have different rows that display different types of views Jon (11:15.71) So for one, you know, if your list was simple and you only had one type of view, like that's the easiest one to explain, right? We can say like, Hey, I want to deque a reusable cell that I registered for item ID is my ID of the cell, let's say. And then iOS would maybe give you one back that you had previously used that it was now freed up again to, to reuse. Or you would have to create a new instance if it was null. And I think now they might create one for you when you call them. minor detail, but the idea was as you're returning these views with the proper representation of the data for a given row, you know, you're the user scrolling through the list and as those items kind of scroll out of view of the list, that cell that would then get kind of shoved back into a queue for recycling for an iOS would handle that. They would kind of say like, Hey, this one's not visible anymore. I'm going to go hold onto this and we'll reuse it later. So that as we're scrolling through, I don't have to keep. creating new instances of this view over and over again, we'll just reuse it. And as we ask you for that one, you know, a cell back, you'll get a reused instance. And then you can say like, if the cell was just like a label with text, right, for the item, well, I know that cell already has that label in it. I just have to change the text to have whatever the text is from the new item I'm displaying as we're scrolling. And so this whole like recycling concept, again, I don't, I don't want to say this is a new idea, I think probably even like wind forms, there was some, I feel like I remember the idea of like a virtual list of items. Allan Ritchie (12:49.345) I don't think there was. Jon (12:51.954) WPF at least. Somewhere in there. Allan Ritchie (12:53.02) Yeah, WPF would have been, but Windows Forms was... That was just shut up and let your app lock up while it renders everything. Jon (13:00.606) Do events or whatever? What was the what was the thing that you called that kind of told the threading to like let some Other UI stuff catch up Wasn't it do events? Early early VB anyway this whole yeah, so this whole recycling concept like, you know again Ios is kind of where I first became familiar with it and then as I learned You know cuz as you want does when they're writing a book Allan Ritchie (13:09.784) I don't remember that either. You're going back too far for me man. Too far. Jon (13:26.154) you learn how to write what you're talking about because you actually don't know until you figure out that you have to tell someone else how to do it. And so they had a similar pattern with this adapter, this list adapter, and there was a generic version of it exposed in C sharp so you could give it your item type. And you would have to return things like how many items are in my list, what's the identifier for a given item position in the list. And then same idea, maybe I'm confused. I might be confusing already RecyclerView. Allan Ritchie (13:57.764) No, because Android didn't have the concept of reuse. You just gave it a cell. I remember you had to do your own reuse. Jon (14:03.922) No, it did have reuse in the in the base list adapter, but it was kind of very rudimentary at the time. And maybe you had to manage some of that recycling yourself. I'd have to see I should have gone and pulled out the book and read it. Allan Ritchie (14:16.677) That I do remember. I remember that I had to control that myself back in the day. That one I remember because Android, being a non-Android lover, always had the performance issues first, never iOS, right? So that was the one where you had to get funky with how you were reusing cells. iOS, you could kind of abuse and it would just figure things out for you unless you had some sort of crazy kind of layout. But... Jon (14:27.86) Yeah. Jon (14:41.866) I mean, you could always do the bad thing of never, you know, reusing cells on iOS, right? Like you could in theory always return a new instance of one. And I think we saw that enough too. It's like, why is my app so slow? Cause you got to do it the right way. Allan Ritchie (14:54.712) It wasn't really though, but yeah, just Android. Android was always a pain. I always saw the performance issues on the Android and that's where, the way I remember the call was it had it, you could just return any instance. You didn't have to, you could knew it right up there. But I think they had like a hold, that's right, they had a view holder. That's what it was, do you remember that? Jon (15:09.069) Yeah. Jon (15:14.346) Well, that's RecyclerView still too. So we're clearly, you know, rusty on our history, but, but that, that concept wasn't lived too long. I want to say, however, you know, talking about like the history of, of Xamarin forms and now Maui, like one of the interesting things is that I think even till this day, our list view implementation might still be based off that old adapter. It might've gotten upgraded to RecyclerView along the way at some point, but, um, Allan Ritchie (15:19.321) Indeed. Jon (15:41.422) You know, this has kind of been one of the challenges and one of the themes of this conversation too is from a Maui perspective, like the underlying platforms keep changing things and it's, it's hard to one know when you can update to use those new things. I mean, not to know when, like we know, you know, whatever version of Android and whatever version of iOS brings new, new API changes, but it's kind of the decision of, well, how back do we want to, how far back do we want to support? And, you know, when is it safe to kind of bump that minimum version that we support up so that we can use some of these new things that sometimes like are just way better performance implementations. And like we're at the mercy of the OS, you know, to, to make that kind of better until we are able to use those APIs. Um, but, but the list like on Android recycler view was the, their next iteration, which was in a Android support library at first, right. And now it's an Android X package. And that one brought things much more close to how iOS was doing things with their adapter pattern, right? Like there's the view holder and there's a call like onRecycle, you know, view holder or something like that. And it's the same idea. You have to go update the thing. You know, you register the different... what type of, like you could tell it what type of view holder I wanna use for a particular item position. And that was a method you'd have to override, right? They'd be like, give me the item view type. And so you'd have to manage like, oh, like index five is actually this type and index six is a different one. And with that, they would call back in and ask you for the view holder. And then you'd go update the label text and do whatever you're gonna do and make everything work that way. Allan Ritchie (17:18.916) And it worked pretty well. It was a good cleanup from the original Android ListView. Performance was a big time gain there, too. Jon (17:23.735) Yeah, absolutely. Yeah, yeah. And so that's kind of the history of those two platforms. And with iOS, I guess the one thing that we haven't touched on yet is, UI table view still exists today, but they did also release this UI collection view. And I wanna say that was, it must not be any, it must have been at least in iOS 10, because that's what we were supporting in Maui as a minimum version. And that UI collection view had, it was kind of like the UI table view, but not quite. The similarities were kind of like the get cell was still a concept. Um, but the, I think the idea always with the collection view is they were trying to separate out the actual layout of the cells from, you know, being constrained to like, Oh, I have a thing that scrolls and you know, every item is like one on top of the other or whatever. Like I don't think you could do a horizontal UI table view. Right. Yeah. So UI collection view. Yeah. And like, like you said, columns too. Right. So that was kind of the idea or like, I think we've, they've even demoed out like, Oh, the, you know, like the album cover, like flow layout, like there's all sorts of things you could do in theory by customizing. Yeah. So. Allan Ritchie (18:21.764) Yeah, they got into columns. No, no you couldn't. So then they got into all that stuff. Allan Ritchie (18:40.852) I'm gonna care so do you I guess yeah Jon (18:45.59) That was the kind of new thing. And, you know, at some point along the way in Xamarin forms, you know, I think there was a realization of like one list view isn't cutting it for those other scenarios, like a grid layout or a horizontal view list view. But there was a little bit of, I think, trepidation of ripping out the implementation of list view and changing it completely because like you said, at the top of the show, like a scrolling list of data is, is kind of, you know, foundational to every app. Like I don't know that there's really many apps that get away with not having that as a big part of their interface. Allan Ritchie (19:25.004) Oh, you have to. It's it's almost a no show without it. I can't even think of a case where I wouldn't use a list to you unless it was like a prototype. Jon (19:29.42) Right. Jon (19:35.07) Right. So like scrolling lists of data and historically phones are slower and, you know, less memory. And so like the concept of virtualizing that list was important too, maybe to a lesser extent in some cases now, but it's still, it's still important. And, and so like, as things evolved, you know, this idea, and this was before I was on or, you know, running the Maui team, uh, at all, um, is I was still doing component stuff in Xamarin. But at some point, you know, they kind of said like, let's do this new implementation. We'll make it backed on the UI collection view. Uh, we know we can achieve like the same concept with Recycler view because Recycler view also brought the concept of layouts of separating layout from data. And so they built what, you know, is now known today as collection view. Well, fast. forward a while and Collection View is, you know, it's a thing, but it's such a hard... It tries to do a lot of stuff, right? I think when they built it, it was like, this thing's gonna be the next best thing. It's gonna handle every scenario that you can think of to throw at it. It's gonna do everything. And kind of, you know, unfortunately, I think the complexity of trying to make... a cross-platform abstraction of that, you know, kind of customizability is really tough. And where we've, we've ended up with it is it's like, well, it does a lot of things, but it doesn't do a lot of things very well always. Um, and so, you know, it's something we continue to work on. And I think it's something that's achievable in a lot of cases. Um, but there's just so many edge cases of. Things that people are going to try and do with these types of controls that you can't account for before you see them run into it. Like one. Allan Ritchie (21:23.472) I mean, I was just going through some of those features right before we started this talk. And it's crazy. I started it. I started probably a list of like five things and it blew up to like, here's all the things that I'm going to use here. And it was like, you know, that's a lot. It's a lot. And it's Jon (21:28.056) Yeah. Jon (21:39.518) Yeah. And, and, and it's a lot to like make work consistently across platforms where the underlying thing you're using is this, you know, similar, but still quite different, right? Allan Ritchie (21:49.208) Yeah, they don't quite line up. So you have to hack one side or the other to make it kind of work the same or seem to work the same. And, you know, it's, it's kind of that common thing in software engineering where you try and have something that does too, does too many things. and you just can't quite get them all right. So you end up kind of spinning, trying to get all these use cases and matrix of features working together and they just don't, right. Or there's, there's kickbacks to what you're doing. Right. So you have to start finding workarounds and all that stuff. Jon (22:06.507) Yeah. Jon (22:21.278) Yeah. And then also like at the same time, the platform is shifting under you too. Right? Like the one thing that we encountered more recently, uh, you know, somebody is saying, Hey, when I have like 20,000 items or 200,000 items in a collection view, um, you know, they're, they're doing the right things in terms of how they're trying to use the collection view. Like I'm, you know, that's not the problem per se. Uh, but they're, they're saying like, it's really slow. And they did up to their credit, you know, this issue reporter did a bunch of work. kind of narrowed down where some of that time was being spent. And the state that we're at with that particular discussion right now is like, it's actually like iOS changed something on us between maybe 15 or 16 and 17. So like the whole implementation, we had this spot where we implement like the get cell size of the delegate or something on the UI collection view implementation. And like iOS is now calling that method because we've, we've actually implemented it for every item in the data source. I was like, well, that didn't used to be the case. And it was interesting too, cause I went back because they said like, Hey, this used to work well on forms for us. And so I'm like curious and well, what what's changed? Cause I'm looking at this code and not much is different. between the forms implementation and the Maui one. And sure enough, I was able to reproduce the same problem on forms now on a newer version of iOS. So it's like, despite your best efforts of implementing these things, like we've talked about on previous episodes, right? Things change and that can introduce new complexities too. So that's kind of another example. So, yeah, I think that's kind of the whole point. Allan Ritchie (24:00.796) I'm always a big fan of Apple. I've only ever had one massive kaboom from Apple was like the iOS timeframe, iOS 8 timeframe. And that's they changed something huge with collection or UI table view in that one. And all my layouts went kaput. All my constraints went just didn't work. And it was it was a brutal time. But so far since then, I haven't seen those issues. So that's what's Apple doing? What's Apple doing? Jon (24:08.952) Yeah. Jon (24:16.087) Yeah. Jon (24:25.534) Yeah, no, I mean, always bringing the challenge, right? And then we've of course added Windows in Maui and that was another kind of difficult thing because with Xamarin.Forms, the Windows implementation of course was built on UWP, right? Which is, now we're on WinUI, which isn't totally dissimilar to UWP. But again, like where we kind of were at, where the list view... on Android moved to like Recycler view and on iOS, they moved from TableView to CollectionView. You know, Windows has kind of done the same thing as being the latest where the thing we were using, you know, never worked super well, but it was what we had in UWP, but there's like a newer way to do it now that's a better way to do it. And, you know, that only recently started working for us from a C-sharp layer and being able to consume that. Um, and so it's like, okay, well. It's another shift of kind of the underlying implementation of things and having to adapt to it too. So continued challenges in that space. I'm trying to think of what other, virtualization of such a big list of data, having it be able to adapt to dynamically sized items, trying to support a bunch of different types of layouts like grids and horizontal and vertical. There's a lot of snap points. I think we use a lot of the same code for carousel view on all the platforms as well. So pretty big control. So we're going to obviously continue to work on that and make that better. But one of the ideas that that's been floating around too is, is this a good case for a more purpose-built control that doesn't try to do so much? So I know I've- Allan Ritchie (26:17.18) like a grid list view type thing or... Jon (26:19.634) Yeah. So I think, um, yeah. And I don't, I think that's the question, right? It is like, how would you maybe divide out some of these functions so that you're not trying to do it all in one. And can you still like, you know, reuse some of the implementations or how do you fit that all together kind of thing? Um, but my thought has always been the, because we've talked again about how fundamental, like a, just a really high performance, good scrolling list of data is to apps. Like, you know, maybe that's kind of the marker to focus on to start, right? Like make something and make it do it well. And then you kind of go on from there. And I think others have, have tried to do this too, right. Or are, I won't say try there. They're doing it as well. Like one of the, uh, you know, alternatives out there that I've looked at closely for, for my own app has been sharp NATO. Um, so they have their own collection view. Now, have you, have you used that one at all? Or have you looked at it? Allan Ritchie (26:55.892) Great. Yeah. Allan Ritchie (27:14.276) I've looked at it. I haven't used it personally. I probably should because he's got a lot of good controls out there as frame and stuff. And I just haven't. I think it's kind of one of those things you have to know that it's going to last the support cycle, especially on such a such a, you know, fundamental component. So that's one of the challenges, right? And I think that's the case with most of my customers do is. Jon (27:26.957) Yeah. Jon (27:32.546) Right. Allan Ritchie (27:38.844) because that sits, it's under such a fundamental state. It's hard to take those third party components in if you don't know they're gonna survive. Jon (27:47.322) And, and, you know, the sharp NATO and in particular too, like I use the example of do something that, you know, do one thing and do it well. Like that's, that's funny enough. The reason that I decided I wouldn't go with that one was, and you know, no, uh, no shade to them writing all these amazing things, cause they did focus on something that said like, let's make a collection view and it'll do a little bit, but one of the limitations was they really thought, hey, every item should be the same size in your list to make it fast. That was the easiest way for them to implement a really good version of this control. It's like, that's great if that's your use case, awesome. Unfortunately, well, my list needs items of varying height and that doesn't really cut it from my application space. But for those that it does, seems like a really solid control. I haven't looked at myself personally, I know Telluric and Syncfusion have their own list views too, have you looked at those? Allan Ritchie (28:43.8) I have looked at Syncfusions. It's in use in a couple apps I've worked with. It's done its job. It's like basic list view. I don't think we've tried to do anything grid based with it. Kind of going back to the Sharp Naito, just one thing I wanted to say because I don't want to cut it up or anything. The person that does it, he does a great job. Jon (29:06.743) Yes. Allan Ritchie (29:08.265) He's done a lot of those things and if you are worried about taking on these third party libraries, you can always fork it. You can fork it. It's open source, man. Take it in. Jon (29:15.203) Yeah, they're open source. Yeah. No, I, I agree. And like, yeah, like you said, there's the, the collection view isn't the only one that, that they've put out and the fact that they're putting these things out in the open as open source to like kudos for doing that, right. That's not an easy, an easy adventure to encounter, especially when people start leaving issues and feedback and everything and, you know, want you to do basically their app for them. So, um, yeah, I don't, I don't. Allan Ritchie (29:43.376) I was going to say his name but I don't want to do it in justice in saying his name wrong. Do you know his full name properly? Jean Marie Alphonseau? My apologies if I said it wrong. Jon (29:49.978) I was thinking the same. It sounds as good as I would be able to do. Sorry if we messed that up. Yeah, we'll drop some links to some of those too, because I've always looked at them and those libraries and there's more than a couple I think at this point. And I've used a few of them in my apps and then they look really awesome generally. Like I like the direction that they all seem to go with it. Allan Ritchie (30:15.664) He did a material frame with an acrylic, what's that glass frosting effect? I love it. Love it. Jon (30:17.687) Yeah. Jon (30:22.27) Yep. So yeah, like there's alternatives out there. We'll talk a little bit more about, I've been working on one too, so I'm gonna spoiler alert myself there too. But actually it's maybe a good segue into it. One of the things that I won't say has necessarily held back implementations, but I think it's caused. Allan Ritchie (30:34.644) shameless plugs. Jon (30:47.99) developers to not think about the problem space in the right way and get themselves into a lot of trouble. And I think you shared the same sentiment as I do, maybe for slightly different reasons. It is really, if you look at the latest implementations of all the different platforms, like the RecyclerView, the UI CollectionView, the Windows, there's a new interface that you can use as the source called IelementFactory. All of these do kind of one thing in common, which is the pattern. that they use, I'm gonna refer to as the adapter pattern. So the idea being, that's a mobile app probably, or I guess on Windows it's a Windows app, but it could be a low end machine. I wanna scroll through a list of data, but I shouldn't really have all of that data probably sitting in memory, even if it's smaller items. Maybe you can, maybe you can, there's an application. Allan Ritchie (31:41.803) Yeah. Jon (31:45.438) And more importantly than sitting in memory is kind of the way that you feed that data into the actual control. So all of these native platforms, the pattern is give me a view for this item. Give me a view for this item. Give me a view for that item. Which is kind of that, you know, one direction pulling from the source of data to get what they need to display. rather than you pushing to that source and that control and saying, here's all my items, here's all my views, here's what I'm doing. And so when I started looking at how do I, you know, can I make a more modern version of a scrolling list control for Maui? For my own app is the real application of this. Like that's why I did this at first. and to better understand the problem space, you know, to try and pull back some learnings to Maui itself. Um, I decided that I really wanted to go and use this similar pattern. Uh, for me, it was kind of like my data is stored in a database. And when I was using, um, collection view from Maui, you know, I would basically pull out a bunch of stuff and put it in an, in an, in an observable collection. I hope I don't have to say that word a bunch more. And. that observable collection was bound as the data source to the collection view control. Well, that kind of presents a few problems, right? Like as I'm scrolling through the data, you know, I have thousands of records. How do I, I'm not gonna put those all in the collection view. It might be okay, but I didn't really wanna always, like every time that data changed in the database, am I like refilling that collection view? Am I just trying to swap out the item? Allan Ritchie (33:22.278) That's a ton. Jon (33:38.742) that changed, there's just a lot of record keeping that I really don't wanna do, that changing the pattern to this sort of adapter pattern really made much more simple in my mind anyway, especially if you're dealing with something like a database backed thing. And so that was the path I took, and I created my own kind of abstraction over what that adapter looks like. And... So if you're going to use my control, you have to implement a data source, an adapter. And I think I even put in there, like I, yeah, people like their observable collections. I get it. We're familiar with them, but you know, I'll hold off one second and you can, you can share your, your thoughts to the world. Um, but. Allan Ritchie (34:18.996) I'm about to go on a rant on that one. Jon (34:28.106) I think I even threw in a implementation of my adapter that you could feed a observable collection to. I probably shouldn't do that because that's just encouraging bad behavior. But there might be some plausible scenarios that you might wanna do that in. The other option is like, for anyone doing any of these too, like with a collection view on Maui, you could always implement your own observable collection. like the interfaces yourself, right? And I could have done that too, and still gone and talked to the database to kind of broker that setup, that connection. But like how many people are gonna go actually do that? Probably not that many. Like it's not hard, but I feel like it's not the most obvious thing to do either. So. You know, that was my one of my main goals is like, can we move closer to what the actual pattern being used on the underlying implementations is and so far I like it, it seems to work well for me but we'll see if others feel the same. Now, on the, the topic of observable collections, how do you feel about those. Allan Ritchie (35:38.212) They have their place. It's just people use them like, uh, like toast and peanut butter, right? They put it together for everything and you don't need it. You just need a list man. If your data source isn't changing. Um, like the, the one I love to see that, and I see this all the time, this one drives me absolutely bonkers is people take the observable collection. Okay, you can add an add range so that it doesn't redraw 10,000 times for adding items. I see that all the time too. But the big one is that I see all the time is that you pull the refresh and what do you think they do and pull the refresh? Jon (36:15.439) They create a new instance of an observable collection and fill it up. Allan Ritchie (36:18.072) right. So they didn't even clear and then kind of add range. They just reinstantiated. Jon (36:24.764) Well, but add range isn't on that by default, right? Allan Ritchie (36:27.692) No, but it's stupid easy to add. Like it really is. Jon (36:29.97) No, I understand. But that, so this is another problem that I see, have seen is, you know, you've got a, an observable collection. Maybe you're actually not newing it up every time you do something, but like, maybe you hit clear and then you loop through all of your items and call add on each of them, right? So what does that do when you do that? Yeah. Allan Ritchie (36:45.64) redraw redraw. Yeah, it's bad. And people keep doing that. And this is why I wish that the official pattern wasn't. observable collection. It's just list that happens to work with I N P C right there. They notify property, right? Not the actual collection change stuff because think about it too. And you can speak more to this is when you have that I notify collection changed versus an I list in Maui, you have to you actually have to implement that extra. Is it an I is it a collection that we can observe? Oh, it is. Here's the whole list of new Jon (37:03.862) Yeah. Allan Ritchie (37:26.226) get it out of the box you guys just have to code it because everyone does it right Jon (37:30.482) Exactly. Yeah. And yeah, to your point, like you can, you don't have to use observable collection on the, on the collection view, right? Like use the list. Allan Ritchie (37:38.768) So a case where it does matter, right? So stop using observable collections. That's the first thing to stop. Just use a list, man. Please for the... Jon (37:47.058) We should almost have like a another property that you have to like opt into. Like, yes, I understand that I probably shouldn't be using this, but I know that I want to, so yes, let me. Allan Ritchie (37:57.684) You could almost have one of those, uh, those analyzers, analyzers going, what is this? Well, do you know what you're doing with this? I do. Do you know what you're doing with it? Jon (37:59.906) You have to sign a waiver. Jon (38:05.654) You know what, that's not a bad idea. I mean, I'd rather like, you know, avoid people being able to put themselves in that state, but while we still have to support the, you know, using these things, like that actually is not a bad idea. Like look for like a loop, you know, through a bunch of ads, right? Like anytime you're, you're adding to an observable collection within a loop, be like, Hey, do you know what this is doing? Cause if you do, you might not want to do this. Allan Ritchie (38:28.904) But you know, sad thing is I see it all the time. I see it all the time and they're like, it doesn't perform. And it's like, just if you run a loop here, man, you'll see it's going slow, right? Jon (38:36.278) Yeah. Well, yeah, every time you're calling ad, it's firing all the events, which means we're telling the native control that the data sources changed when really your intention probably is to load everything and then do the one like, Hey, stuff changed. Allan Ritchie (38:51.212) So the question usually is, when do we use observable collections? So there are cases if your data is in motion, like we're not just talking ads. If your data is actually in motion, like things are moving, things are being removed, etc. That's a place where you might want an observable collection. Right. So the one that I like to do so. So Shiny and Shiny, I have I Beacons. You ever remember I Beacons? Jon (39:02.987) Yeah. Jon (39:15.254) Yeah. Oh yeah, I wrote bindings for libraries around those and all sorts of stuff. Allan Ritchie (39:18.38) Yeah, so I still do them. I have a full like... native C sharp version of it for Android. Anyhow, what tends to happen with those is, you know, your distance to them is kind of changing constantly. So let's say I'm running a scanner, like a tri-quarter. I wanted to say something nerdy for this one, so I got it. So you got your Star Trek tri-quarter scanning for these beacons, right? So obviously, you know, there's several states of it near, intermediate and far, right? Or there's just, it's out of range, Jon (39:50.968) Mm-hmm. Allan Ritchie (39:53.026) obviously your individual list items as you pick up these beacons you're getting an ad as you pick them up the actual individual item might be changing near far etc right so that's changing but then there's also the case if you don't there's not really an out of scope Jon (40:04.558) Mm-hmm. Allan Ritchie (40:11.1) beacon, right? It's if I don't hear from it and say five seconds, it's probably at a range. So you have to remove that from the collection, but that's data in motion. That's where an observable collection matters. Not for a database backend really, right? That's not really in motion. I mean it is, but not in real time. Jon (40:15.474) Yeah, then it's probably gone. Yeah. Jon (40:28.63) Right. So, so in, and so in, like in your example, like the, the difference being, if you wanted to articulate it, doing it the wrong way, right? Like you could also have gone and done a scan and then every, you know, that was your new source of truth. Every time, you know, you, you scanned, let's say obviously for beacons, like that's not the way they work and that would be really expensive probably to do. But if that was the case, then you would like clear your Allan Ritchie (40:56.692) Clear ad, clear ad, clear ad, clear ad. Jon (40:57.194) collection and add them all in and like yeah right like but no the whole point of observable collection is to like observe only the changes that are happening which doesn't include the initial state either. Allan Ritchie (41:08.684) Yeah, and it's now in that case, the observable collection becomes a lot more complicated, but it's being used in the proper way. Right. And. Jon (41:16.062) Right. And to tie that to a collection view, like to display that, that's fine, like that's great. That's still a good use of it, right? Like if you're showing that in your UI. Allan Ritchie (41:23.449) Exactly. Exactly. And it makes sense. And the performance is a cost that we're willing to pay because that's what it needs to do. Right. When we're talking in terms of simple, simple data, it doesn't need to do that at all. Right. Jon (41:37.258) Yeah, yeah. And that's kind of more my point too, I think about, not that necessarily having a thousand items in memory is gonna be a problem anymore, but it's more the idea of where are those items coming from? Are you just using the collection, the observable collection as a sort of... transport or proxy to get data from here, you know, one side into the actual view. Cause like, if that's the case, like that, you're just doing busy stuff in the middle for no good reason. Allan Ritchie (42:09.204) Well, here's the other thing that people think about collections, right? They think, Oh, I've got to virtualize it by, remember the old web days where we, where HTML just rendered everything. There was no concept of virtualization, right? And people would just load a hundred items up. Like we had that really complex pagination pattern nowadays. It's like, man, think about if a record's, you know, a couple of K, like, let's say, let's say it's a thousand bytes. It's probably not per record. You look, you can load up. Jon (42:19.423) Yeah. Jon (42:32.279) Mm-hmm. Allan Ritchie (42:39.158) or 5,000 records easy. It's not going to be a lot of data across the pipe. It's not going to be a lot of memory on your device. Just load it. And now that we've got like RecyclerView and, and all these kinds of virtualization patterns right in the UI, just hang on to the data. You don't have to make that, that API call, you know, however many thousands of times you need to, to get all the data, just make one call and get it. It's not a lot of data. People just hear that number 2000 and they're like, Oh my God, that's a lot of data. No, not really. Jon (42:57.718) Yeah, yeah. Jon (43:05.726) Yeah, it's a lot of items, but even though it's like, yeah, well, it's really like, you know, three megabytes or something like, whatever, our phones have gigabytes now. Yeah. Allan Ritchie (43:10.904) Oh, that's huge, man. No way it's megabytes either. Cause if you think about it, like we're talking, if you're returning like megabytes of data, it doesn't matter. It can be one item or 10 items. It can be slow, right? But Jon (43:23.614) Well, that's where I got to with my pool app too, right? It's like the whole database, like I'm using SQLite now. The whole database, I think is like under a meg for the average user locally, like for their own set of data, right? So it's like. It's nothing like even if I wanted to load all of the records. And I think at one point I did that for some of the pages is just like, it's easier to have them all in memory. Cause I needed to do some filtering and you know, whatever summarizing of, of all the data over them. And I just kind of finally realized the same thing of what you're saying is like, Oh, this yeah, it's 2000 records, but okay. Who cares? Allan Ritchie (43:40.305) Yeah. Allan Ritchie (44:00.24) I always like to say with these things right is don't solve for a problem you don't have. So right if you're doing it too early and you're putting in pagination stuff you're generally causing the issue you were trying to solve in the first place. I swear I've said this recently to people too. Jon (44:05.922) What's the first rule of optimization, right? You don't. Jon (44:15.634) And this is also why I like the adapter pattern for a ListView, right? Because let's say that you actually do need to worry about that. Like you have 200,000 records and they're all three kilobytes or something. Yeah, like whatever. Let's contrive an example that you're probably already doing something wrong if you get that far. However... Allan Ritchie (44:36.157) Yes. Jon (44:39.542) even if it's just a lot of, you know, number of items, like the adapter pattern is more about, hey, like tell me how many items are in your list and we'll deal with, you know, asking you for them as you please. But with the whole like, oh, I don't wanna load all 200,000 into the collection or the observable collection. Cause like that probably is gonna be a bit slower to start up your app if you do that. It's probably still not horrible, honestly, but it's gonna be a bit slower. Allan Ritchie (45:02.725) Yep. Jon (45:07.726) Um, and so what, then you'd see people like talking about the page, uh, pagination stuff, like I've seen so many implementations where people are trying to figure out, well, when am I getting near the bottom of the list? So as the user is scrolling so that I can load more, right. Right. And, and like, it's, you know, with the adapter pattern, like, that's not a thing. Like even if all of your data was on a service somewhere, you could, you could design it so that you're like, tell me the number of records upfront. Allan Ritchie (45:19.704) Yep. Start. Yeah, start the virtualized loading. Jon (45:35.486) And that's so that I know to tell my adapter and like, I'll figure out getting those records as you need me to get them rather than trying to figure out, well, when am I scrolling and how am I doing it? Like that just, you're, you're setting yourself up for more problems. The more you try and divide this out. So Allan Ritchie (45:50.84) Exactly. But that's what people are doing and that's where I think a lot of these performance issues happen. Just because they're optimizing for a problem they don't have. Just load those 2,000 up. If you've got 200,000, okay, that's a problem you need to solve. But if you don't have a performance problem, you don't have a performance problem. Jon (46:10.694) Don't invent one. So what other kinds of things are you looking for in lists that you're building apps with these days? Allan Ritchie (46:11.825) Now don't invent one. Allan Ritchie (46:20.24) So I had a complicated one recently, really complicated one that was not easy to solve. So it's one with grouping. So it has the grouping of the sections, not a big deal, right, that's usually pretty easy. What it does have is kind of that responsive layout, right? So it has multi-columns. Jon (46:34.763) Mm-hmm. Allan Ritchie (46:41.708) And those columns are rows really like each column has its own rows. It's not trying to render rows. It has to render columns with rows. If that makes sense. Jon (46:51.594) So do you have like a bindable layout inside of your item template or like how are you rendering those rows within the row? Allan Ritchie (47:01.14) We had to get really hacky with this one. There was a lot of challenges with that because that's not something that comes out of the, it doesn't come out of the box on either platform either. Right? So, and it obviously is not gonna come out of the box from Maui if it's not coming out of the box from the platform, so. Jon (47:10.795) Mm-hmm. Allan Ritchie (47:19.624) Oh, that one had to get hacky. And at one point we'd even said, you know what? Web is built for this. Like if, if we needed to, this is where we can go blazer and it's still fine. Cause it'd only be that list in blazer and blazer and, and web. I mean, heck, if you want to do react, fine, we're not going to debate the tech here, but I can wrap that in that view and do that complicated thing. And web does that well. Right? So we don't have to, we don't have to rely on the native controls for all these. Um, if there's a simpler path to go. So. Jon (47:42.934) Yeah. Allan Ritchie (47:49.838) That was kind of the do we keep trying to fix this control which just is not really working well Or you know, you've got to got a plan your escape plan Jon (47:55.891) That's an excellent point though. That's probably something that people should consider more in general, especially given that Maui, we've done some stuff to try and make the web content thing a bit better if you really wanna mix in Blazor, right? Like that can be a solution. Like I like that point. Allan Ritchie (48:15.909) For this one, it was like... Honestly, there's so much to play with and there was kind of some platform overrides that we were having to mix in. And it's like, you know what, if we just go blazer, it's still going to be performant, like this doesn't, I mean, people have this concept of performance. What's the first thing people complain about with performance right on the list is they do this turbo scroll and it's like, you users don't do that. I know it jitters a bit in certain cases and that sucks, but you users usually don't care. They're like, does it work? Can I get to the data? That's what they care about. Right. Jon (48:34.295) Yeah. Jon (48:47.018) Right, right. Allan Ritchie (48:47.638) jitters just a bit they'll be like oh okay whatever Jon (48:51.786) Yeah, no, like, yeah, I wonder if apps started kind of doing more like telemetry on, um, yeah, how many users are scrolling? Like how far do you use users usually scroll down a list, right? Like I know in my own app, I have like the timeline of different logs that you store for your pool. So like, if I add chemicals, I want to log what I added. If I, um, do a test of the water, I want to log those results. And so as I'm doing this, I build out this timeline. view of a list and it has all sorts of different view types right every type of log you can do and i think there's like five different types of logs that i allow right now they all have their own representation but like now i'm almost curious to start trying to log like how far back do people scroll in that list on average probably not very far Allan Ritchie (49:40.74) Well, let's question the business too, right? Because at that point, I mean, I don't know much about pools. So forgive me for quoting this wrong, but I would basically want to pull up a summary screen. When was the last time I did A? When was the last time I did B? When was the, I don't want to scroll through that and figure it out, figure it out for me. That's what the purpose of your app is. Right. Jon (49:57.258) Yeah, no, and that's there too in the main view, right? But it's like, if you do want to go back and look at like a history of items, it's there. But yeah, to your point of like, you know, I'm more the do as I say, not as I do here because you know, you're right. And I probably didn't need to worry as much about that scrolling performance, but I did, which has led me to build the thing I built. But yeah, at the end of the day, it's like, well, how much do people use that? Allan Ritchie (50:24.86) That's the other thing I like to argue from the buttery smooth. I hear that one. You say that one all the time drives me crazy. I love it. I love it, but the price that you have to so when you when you move over the enterprise world, right of building these big massive apps. Jon (50:31.018) Yeah, my list is buttery smooth. Allan Ritchie (50:41.444) Right. The cost of getting buttery smooth on every single list is like the cost just for that, say that last 10% of performance. It goes from maybe it took you. This is really bad numbers, but let's say it took me 10 hours to build it to get that last 10% performance is probably like 40 hours. Right. So it's four times more the cost just to get that and it's like your user doesn't care. Jon (51:00.69) Yeah. Jon (51:09.694) Yeah, no, and you're right. Like, and I, if I think about how, you know, the time it took me to get to where things are at, if you don't consider the making this whole new control for it, uh, I still, you know, I'm sure I spent enough time like flattening layout hierarchies for my list item, you know, data templates and stuff like that. Right. Like, you know, same idea. If I had just kind of left things. alone instead of trying to, you know, micro optimize. Oh, I can use one grid here instead of, you know, two nested controls and that kind of stuff. Allan Ritchie (51:40.228) I mean, it's a great, it's a great lessons learned, right? So there's always stuff coming from it. And there is going to be cases where that buttery smooth does matter. But you can't, it's hard to bill your customers for that, right? Unless they're asking for it, you know, be like, well, it only took you 10 hours. Let's just spend another 10 hours and optimize it. You're like, well, 10 hours, 10 hours to implement it, but it's probably going to be more like, again, four times that to just make that last 10% be there. Okay. Let's not do that. Right. Jon (51:42.828) Yeah. Jon (51:47.725) Mm-hmm. Jon (51:51.911) Yeah. Jon (51:59.563) Wait a second. Jon (52:07.466) Yeah. Exactly, oh, we don't care that much. Allan Ritchie (52:12.462) And that's just it because your users aren't going to turbo scroll. They don't care. Usually it's not like it's a game, right? So just plan for what you actually need, what your users actually care about. Jon (52:26.506) So the other thing that I touched on when you talked about like having, you know, kind of a set of dynamic rows within a item, and this isn't necessarily that this would have been a good solution for your case, but it made me remember, you know, we also, I also see a lot of people that are trying to use a collection view where really a simple, like bindable layout would suffice, right? Like if you have a view. and you know you're not gonna like have hundreds of items in that list. I'm not saying this is a blanket thing, but sometimes it might be easier to use like a vertical stack layout as a, you know, bindable layout with your template in it and represent your UI that way within a scroll view. Like I saw this recently with someone where, you know, they had this. Allan Ritchie (53:10.685) Yep. Jon (53:19.338) complex setup and they're like collection views being kind of weird and we need it to you know use like Collection views within a thing and i'm just like well how many items do you expect to ever have in that list? Oh, well no more than like three or four Well, either just like find if it's dynamic and you need it to truly be But like then use the bindable layout don't you know, or if it's not that dynamic like Allan Ritchie (53:33.553) Yeah. Jon (53:43.682) hide and show some controls and just build it out statically if you know that you're only gonna ever have this kind of set of controls, right? Allan Ritchie (53:50.652) Well, you got to be careful because I've seen that one blow up in people's face too when they do images, right? So if they don't have like optimized images, it's going to load all those images into memory. But again, if you have a small subset like five items, like a couple jobs or tasks, you've got to do in some work, right? It's also great because I've seen people do like multiple collection views or multiple list views and it like scrolls within scroll and it's like no, no. Just render the whole thing and wrap it all in a scroll view. Problem solved, right? Jon (54:00.343) Yep. Jon (54:10.846) Oh yeah, yeah. Jon (54:17.406) Yeah. No, we, we see a lot of cases too, where people are nesting like collection views inside scroll views and stuff like that. And it's, you know, yeah, one, like don't, don't do that. Um, just no, uh, two, especially on iOS don't do that because they're like collection view on iOS is basically its own scroll view already. Allan Ritchie (54:39.458) Yep. Jon (54:40.586) and that doesn't play nice together. And this is like another challenge too, right? Cause people want different things. And so one of the other ones is, hey, I have a collection view and I want it to kind of only size itself to the size of the content within it. And it's like, and kind of like I said, at that point, like maybe that's not the right control for you if you expect to always have content that's smaller than, you know, that certain amount. And those things don't work like. Allan Ritchie (55:04.361) bright. Jon (55:08.006) UI Collection View does not want you to constrain its size if you, or to check to try to do that if you have a lot of data in a source. Like that's another case where. How do you figure out what the size is to shrink to? Like, I guess you could start to do like, oh, if I'm fewer than 10 items, maybe it's fine to call that and figure it out because what's happening when you do that is it's going and asking, what's the height of every item? I need to know that the total size of the collection view. Oh, you have a thousand items? Well, how big are each of those items, right? And then you start. Allan Ritchie (55:39.504) I love that you've gone through this thought pattern too, because it's like you have to solve for another customer and it's like, don't just, don't do this. Jon (55:45.098) Right, right. And this is kind of the whole like purpose, do one thing well, right? So it's, yeah, I think that's probably underrated in the sense too, of people not like people getting stuck on like, well, no, this is the way that the UI has to be presented rather than. You know, trying to be a little bit more creative at, well, this isn't working well. You know, maybe there's a better way to display this information, right? Allan Ritchie (56:11.064) Yeah. Yeah, it doesn't have to be a one size fits all. It doesn't. Jon (56:16.35) So anything else that you are finding you need in a good list control? What else can I build for you? Allan Ritchie (56:22.028) No, that's well, multi select, I think grouping, pretty much everything, but nothing or just, John's trying to sell me on, so I gotta give you your plugin of the week, right? You can't toot your own horn, right? Jon (56:25.89) Yeah, I think I got those. Jon (56:37.544) Yeah. I gave yours, so you'll have to do mine. And we'll have to find like, you know. Allan Ritchie (56:39.328) Yeah, it seems better. So our plug-in of the week is John's virtualized list view. Did I say that? Is it virtualized or what? It's a virtualized list view. Jon (56:47.778) Uh, virtual list view, but yeah, I mean I'm name what's in a name anyway. Allan Ritchie (56:51.828) So, reds, you're gonna have to explain that name to me one day. Virtualized list view. So John is upselling me on this right now because I've got a performance problem in a collection view. Now it's a case, I think this one is actually a Maui bug and that's alright. I can either fork and fix or I can go one of these separate routes which is exactly what I'm gonna look to do. Oh. Jon (56:55.669) Yeah. Jon (57:13.718) I think we need to make some t-shirts at some point that just have on it fork and fix. Allan Ritchie (57:22.005) Well, it's tougher to fork Maui and run that, but let's talk about yours because yours... Now John is a busy guy. He has a tough time fixing open source. In fact, if you don't know him directly, it's hard to get him to fix his OSS, but you can always fork and fix it. And he does respond. Every time I fork something and fix it for you, you put it in. I mean, you can't ignore me, but you can. But it's nice. Jon (57:38.647) Yeah, that's right. Jon (57:42.562) Do I? I mean, yeah. No, I think even in some of my bios, I kind of allude to the fact that I have way too many open source projects. I have a very hard time not chasing the shiny new thing like a squirrel, but. Allan Ritchie (57:55.165) You do. Allan Ritchie (58:02.024) But this virtualized list view, you've kind of been all over. This is kind of like the seems to be a case where you enjoy working on it. So. Jon (58:08.93) It is, and it is very selfishly motivated. Like I said earlier too, right? Like my app, I wanted what I wanted and I wanted it to work well. And that led me to this whole, like, I bet you I can try and learn something and at least and maybe do something better. And maybe that helps inform something that we do in the future in Maui too, I'm not sure. So yeah, I'll put a link to the GitHub repo. It's on NuGet. I won't promise that I won't break you between releases because my own QA process for my own stuff is not that rigorous. However, it kind of aims just to, like I said, do one thing well. I don't support grid layout style at this point. I do support horizontal scrolling. And there is a good reason for that for now. Part of partially the good reason or mostly the good reason is doing the kind of group like header and footer views in a UI collection view with being able to do them dynamically sized as well as all of the items themselves dynamically sized is actually really, really challenging to do properly on iOS. And I actually haven't quite figured it. Allan Ritchie (59:25.324) Enter the use case I just gave you. Jon (59:27.922) Yeah, yeah. I haven't got it working to the level that I would like to see it work yet. Let's put it that way. Allan Ritchie (59:35.716) And that's the case. Maybe it's a, maybe it becomes, you know, Red's virtualized grid list view thing, right? Jon (59:42.506) Right, right, yeah, if we're solving knowing that's the thing, then it's a little bit maybe easier to reason about. But yeah, it does a lot of things, like I said, it implements more of the adapter pattern, so you have to kind of learn that a tiny bit and wrap your head around it, but I do have some helper types, like I think there's like a simple adapter implementation that takes like a I list or whatever, so you can like throw that into it if you really want. You'll have to... Allan Ritchie (01:00:09.66) You have great samples in there too. So, that's it. Jon (01:00:11.55) Yeah, there's example. There's an animated GIF showing the scrolling of a catalyst app. This is a long time ago, and I think it actually scrolls better now than in that example. Allan Ritchie (01:00:22.16) doesn't really give you a good just good just so you know the GIF. GIFs are low frame rate so it doesn't really give you that buttery smooth so people are gonna look at it go it's kind of jittery and it's like no that's just a GIF. Jon (01:00:25.642) Yeah. Yeah, I know, I know. Like this is kinda, yeah. Yeah, no, I had that thought too. I'm like, oh, I really should just put a video up so it shows it better. Oh, that, I'm worried this is gonna be a long episode because there's just so much topic to talk about on the topic. But I have a few more things that I just remembered that I have to get in there. So one of which is... Allan Ritchie (01:00:38.156) Yeah, I was looking at that. Allan Ritchie (01:00:49.256) Get in there. Jon (01:00:53.546) you're going to have to understand how to make things fast for yourself in some cases. So like I have an example that, um, and I do this in my own app that pulls data from a database. And so in the adapter, um, there's a call like get number of sections, get number of items in section. And we pass you the section index, get the actual section itself given an index and get the item. There are times where you should cash things when you're pulling things out of a database, right? Like, you know, if, if you're depending on, and I can't do this for you, because I don't know your data and you have to be the one to make those intelligent decisions around it. So for instance, like with the example, I have that list, like a database of different albums and songs in each album. Um, the number of albums is like, I don't know, maybe a hundred albums. So for that case, it makes sense to do like one quick database call to get the number, all of the different, you know, albums and the number of, uh, titles or songs within each album so that when the adapters like, Hey, give me this section information and give me the number of items in the section, it's fast. And that data doesn't really change often. So like, you know, the point here being as a developer, when you're building these things, like you have to know a little bit of what you're trying to do and you have to make some intelligent decisions, right? Allan Ritchie (01:02:26.144) what you're referring to is the old n plus one parent plus children load n being you know algorithmic or your exponential is the one i'm looking for um load all your children load the parent so instead of making 101 calls you make two calls right Jon (01:02:30.411) Yes, exactly. Jon (01:02:45.29) Yeah, exactly. Well, optimize where it makes sense to. Right. Um, and, and so that's one thing. And the, the library too, like, you know, you get to do grouping, you get to have headers and footers based on that grouping. You can even specify a template selector for the header and footer. So like, if you have different things, like that was another case of me, you know, over doing it when I shouldn't have, but it's there, it wasn't that much harder to do. And then there's like the concept of a global header and a global footer. So like lots of stuff that you can do there. It uses all the latest, you know, native controls. So like the iElement factory thing that I mentioned for Windows App SDK. I know you don't deal with Windows Zelen, but you know, I do. So it does work on Windows. Ha ha. Allan Ritchie (01:03:33.136) not allowed to say anything and I won't. Jon (01:03:36.31) Uh, yeah. So, you know, go, go check it out. I I've been kind of, um, timid on pushing this out more broadly because, you know, for one, like it's got a number of stars and I think some people have tried it out and there's a few issues that are, you know, nothing looks too pressing at this point. Um, but I'd kind of like to slowly get more eyes on it one because I'm not great at, you know, getting inundated with bugs and stuff. So I don't want like. Thousands of people to go like, Oh, this doesn't work or can you implement that? And So but check it out and see if it works for you and we'll kind of keep evolving it from there. Allan Ritchie (01:04:08.636) put it in the shiny templates. There's a lot of downloads on that. We'll see if people start working with it and we'll see what happens. Jon (01:04:11.914) Yeah, yeah, there you go. There was one other thing that I was gonna mention on lists and it's, you know, I think I've maybe scrolled past it already. Allan Ritchie (01:04:23.7) It's alright. We can always bring it up in another episode. Because here's the thing. I'm about to go try this right now. Because I have a performance problem I need to get solved. So this was like John's chance to put a napkin sale out there to me anyways. I mean he already did. I was already going to do it. But it was much more convincing hearing him talk about it. So I'm going to go try it. I'm going to find out if it solves my issue because it probably will. And then I can report back on it. Jon (01:04:29.963) Ha ha. Jon (01:04:44.087) So if. Jon (01:04:49.622) So yeah, like I was gonna say, if there's no more episodes ever this one, then you know how it went. But hopefully that's not the case. Allan Ritchie (01:04:54.705) Hehehe Allan Ritchie (01:04:58.468) Nah, he'll implement stuff. If you bug John in just the right way, especially if it's on one of his babies that he wants to make great, he'll fix it. He'll fix it. Jon (01:05:05.746) Yeah, that's true. All right. I think that you know probably does it like you said well We can follow up in the future if I if I can remember what I was gonna say yet but in the meantime, you know, if you uh, Like the show, please subscribe give us a review on apple podcasts wherever you get your podcasts If if not apple, I think most people use apple podcasts still Allan Ritchie (01:05:27.62) I don't use podcasts. Jon (01:05:29.174) Well, you better start. And we went through a question submitted earlier in the show. If you have questions, please feel free to hit up our website. You can submit them through SpeakPipe, or you can paint us on threads, or x, or email us at show at gonmobile.io. And I think that'll do it for today. We'll see you next time. Allan Ritchie (01:05:51.208) Ciao for now.