Creating A Staggered Grid With Jetpack Compose

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] [Music] [Music] [Music] so [Music] [Music] [Music] do [Music] [Music] [Music] [Music] [Music] oh prince thank you hello everyone happy wednesday welcome back i'm excited to be back after uh quite a bit of time off um i'm also excited uh prince subscribing with prime to show off something i'm very excited to share with y'all now that we're back is um the sub badges prince if you go say something in chat you should have a little badge next to your name i'm excited to show these off it doesn't show up on my screen let me try um there we go mine worked so mine shows a little gingerbread icon next to it hopefully you all can see that um so the theme which is probably not surprising is that all these sub badges are going to be based on the android uh like dessert themes um so i only have two in right now the first time you sub for like one month you'll have a cupcake next to your name and then after two months of being subscribed you'll have a gingerbread and i have more coming but those are the only two on the channel right now and i can only have so many because i'm just an affiliate i'm not like a twitch partner so i can't have like a three-year badge or anything but who knows maybe by the time we get to uh um three years maybe we'll be a twitch partner we'll see that's uh expecting a little bit um i'm surprised that my alert didn't go off maybe it doesn't go off when you like switch your sub but i think you could also on the um chat box there's like a little chat ibmb thing to the left of where you type your text and then you can configure um what shows up next to your name there it probably shows like the first badge because you were one of my first subscribers i think the first badge is cooler than the actual sub badges because that means you were here before everyone else um so welcome back uh today we are going to be uh trying to do the stream that we tried to do like three weeks ago and then everything broke which was um maybe that's possible um but the thing we're trying to do before everything broke was to build a custom layout and jetpack compose specifically trying to build like a staggered grid layout if you're not familiar with what that is i actually did a little bit of cheating trying to google around and see if other people had built something like this already and how they did it and it turns out one of the uh composed sample apps from google solves this problem so if we look at their sample app here i can't unfortunately unfortunately i can't pause the gif but if you look right here this courses screen you can see that it had a list of courses and they were kind of like staggered it wasn't like a perfect grid the same way these cards are here like the first two rows you can see things don't line up a hundred percent with each other um so that's something interesting that i thought would be fun to build and it's not something that is like um built-in to compose right now um i have no idea if it's coming in the future um i know there's something close to it that compose has this experimental component called a lazy grid um which will show like more than one thing side by side i guess um but we're gonna try to build a staggered thing like you see in maybe like pinterest or google keep um so they actually show in this sample app um where the staggered vertical grid is uh i actually need to change this link because it's been updated i'm going to drop this in chat but what i'm going to do today which is maybe a little bit like cheating is i've got this same thing open on my other screen and i'm actually just going to kind of go through it like line by line to try and understand how it works and hi absole thank you for coming by uh go through this line by line try to understand how it works maybe be able to provide like a little more clear explanation of what this is doing and then maybe once we understand that we can kind of modify it to work in our own example so yeah let me know if you have any questions on that idea um i will fill you in on some other stuff that i did before this stream to test this project so when we tried to do this last time we were trying to manipulate the bloom app that we've been working on um and i thought i didn't want to over complicate things i wanted to keep the scope to focusing on like the custom layout the staggered grid idea so i made a new app um staggered grid compose and i'm gonna go ahead and drop this in chat give it a star follow the repo that's where you'll find all the code after this stream if you're one of the people watching this on youtube it should end up on youtube i'll make sure that i put it in the description because last time i uploaded a stream to youtube i forgot to put it in the description and i got some comments on that but i'll make sure to do that this time but uh what else did i want to tell you before we started ah i wanted to show you what we did already so here's a little sample app that i put together that um this is literally just a list of random strings and it's a list of random strings of different lengths and the reason i did that is because i wanted a sort of contrived example that would be easy to port over into this staggered layout so if i was trying to show like a list of strings and i could guarantee they were not all the same length and that some cards would need to be longer than others then i would be able to get this staggered effect that i wanted right so i whip something together that would generate some random strings and right now it just throws them in a strict like vertical lazy column and i'll walk you through that code some of you who have been hanging around are at least familiar with the sort of basic jetpack compose code for like columns at this point but i'll still walk through it so everyone is on the same page getting started and then we'll try to convert this into the like staggered grid that uh we want to build so um let's jump in what did i change so just to again really show you like what's involved in here so i have these helper methods this one just gets a random string so it takes like all the alphanumeric characters and then given some length it will just get a random character and turn that into a string and then i have another one that will give me a whole list of strings so you tell how many you want it will determine a random length of the string anywhere from 1 to 150 characters and then it will get a string of that length and return that so that's the random things that's more like not even android or compose this is straight kotlin code kind of ripped the idea from stack overflow you know how we do in this twitch chat um then we have a text card which is oops they're just a card component we tell it to fill the max with and we give it some whoops oh my god i'm jumping around we tell the card to fill max width and then we give it some text again contrived example it's not like a flashy like card with images and text we're just going to show text on a card so we can keep the focus on the staggered grid that we want to build and then the last thing that i built before this is um a text card list which again is just a lazy column has some custom spacing but it takes in some text that we give it and it creates a card for each one and all of those are made inside main activity i get a random list of 10 strings and then i create my list so that's our contrived example that we're starting off with let me know if you have any questions about anything that i just speed run through if you've been following with the jetpack and post streams a lot of that code should look familiar but of course please like stop me if you're extremely confused and i'm happy to walk through anything and even if you're not extremely confused maybe you're just new to this stop me i'll show you some stuff so yeah we get started one other funny note so i had this idea for a while and i finally decided to do it i have no idea if there's a person out there with 10 000 channel points yet but i made a channel point reward where i have this goofy captain america hoodie that also like covers my face and i thought if someone has 10 000 channel points i will finish the rest of the stream in that captain america hoodie oh this is a good question i think you asked me this last time have i already tried to remove an item from a lazy column maybe you didn't ask me but i have gotten this question last time the short answer is no but i should put that on my mental list of problems to work through on stream maybe if we get through this staggered thing fast enough we can try to do that thanks for the idea um but i'm sorry i haven't done it yet so i i really don't know um so time to think about how to um dive into this so ah gotta hydrate thank you i have my github water bottle back that was at my parents house in michigan for the last several years and when i saw them a couple weeks ago i finally brought this back it's a really nice glass water bottle okay so let's let's talk about um where we're to start with the staggered grid and i didn't know if it would make sense to start by looking at their code and talking through it but i think that because i want to take their code and i want to like rewrite it myself that's when we'll do that i think a good place to start before we just dive into writing some compose code is to try to get a high level understanding of what we have to do to make this work what i mean by that is actually we can go straight to the jetpack and post docs for creating custom layouts so i'm going to post this in chat and i'll give a little bit of context about where where the docs above this lead and how we get here so this first sentence mentions a layout modifier which we can use to change like a single composable in their example they show how to use like this layout with a lowercase l modifier so you could add like custom padding onto a text that's how they do like padding from baseline instead there's if you need to measure and lay out multiple composables we have a composable called layout the difference here it's a capital l so this is a composable function and not just like a modifier that's one way to semantically see the difference this allows you to measure and layout children manually all higher level layouts like column and row are built with the layout composable so a lot of our default components are going to be using this under the hood and so this actually goes on to show how we can use layout to build like our own version of a column i'll just kind of talk through i'll zoom in a little bit more um if i do one more is that too much no this is actually pretty good so we'll talk through like what this really does so we call this layout composable we have a modifier and then we have some content and then it has this lambda that gives us measurables which are basically i think and ask me this as we go through if this is right my kind of understanding from the docs is that these are kind of analogous to like the children of the composable and so these are all the things we need to measure and these are the constraints for this layout that we need to work around and so what we'll do inside of here is we're going to measure and position each of the children so like in this column example um let's see what we do here so we basically go through all of our measurables we map them and then given the constraints we have we we measure how big each of these will take so these namings are kind of confusing so let's think about it this way if measurables is analogous to like the children right so let's say the items in the column we want to go through each item of the column and figure out how big it's going to be and once we do that we're now going to have a list of things that we need to place on the screen so the first step is measure how measure how big your children need to be and then figure out where to place them so now we're going to create this we're going to use this more like layout modifier that we talked about earlier and we're going to make this layout as big as it can be so it'll take max width math max height we're going to keep this running track of the y position so if we're laying things out vertically like in a column we're gonna start at zero that's like the top highest point in the layout right not necessarily the screen but the highest point in the column and then we're gonna go through each of the children we had these placeables that we need to place then we're going to place it x equals 0 saying we're going to place it starting at the left but the top of it is going to be wherever our y position is and then we're going to update our y position based on that height so you can kind of think as we iterate through this lit this for loop here as we iterate through these placables um like it's weird to read but hopefully talking through it that's kind of understandable we're going to take an item we're going to place it at the top and then we're going to basically move the pointer down to right below that item and then we're going to place another one and then we're going to move our pointer down and then we're going to keep going until we're done and yeah that's how a column works behind the scene and so i think uh that's actually a good little thing to walk through is that as we try to build our own sort of like staggered grid um we're gonna be able to do like the same thing so uh let me know if there are any questions otherwise what i'm gonna do next is i'm gonna basically take this code i'm gonna pull it up on my other screen and uh talk through it and try to understand um how it works so let's pull that up on this screen so you all can see my ide and uh we'll make a new file and i'll try to make sure i'm switching a little bit between uh staring at this code and looking at twitch so that as you ask questions i can help answer them but i'm excited to get started i think this will be really fun to build very cool okay so the first thing i noticed um from the you know google sample i'll just put it in here so there's a modifier if we need to put one uh by default we'll just use the default modifier the google one uses max column width and we can give it some dp dimension ratio and then we give it the content that's going to appear inside the staggered grid and this is just a composable function so one thing that i didn't quite like about the google sample and i think this is a personal preference is this idea of like a max column width um and then what the google sample will do inside of that is take that sort of max width compare it to the screen width and determine how many columns to make um but i think it would be kind of nice if like arguably like a a simpler api to just like set what the number of columns should be like let me the caller determine how many columns i want in my vertical grid um and we can even give this a default like two um so i think that's what i'm going to do i want to start by just building something that has like two columns um but we've got this default value in here so we should be free to once we have this working change that and see how the ui updates right so let's look at the next thing we need to do well the first thing is we need to um whoops okay we need to create that layout composable and i'm gonna get rid of that default there so we have to pass in the content and we'll pass on the same modifier that we got and remember this gives us a lambda of measurables and constraints why are you yelling at me it's because i haven't done anything yet um i might need to oh well i probably need to return something it's and um oh we probably need to return something but let's let's go for with this for now so looking at the google one so the first thing we would do in their sample is calculate the number of columns um but we don't need to do that we set our number of columns but we will need to know like how wide each column should be so to get the column width we can do um basically look at constraints figure out what the max width is and then divide that by a number of columns so that's going to be the width of each column now we need item constraints which is got it so let me type this out and then i'll explain it so so we need to set constraints for each of the items yeah so the sorry respond to twitch chat azil there's um when we basically call like a layout at the end um this layout returns something and that will satisfy compose but we'll get to it so we also need to think as we prepare to lay out these children we need to think about the constraints for each individual item and the constraints for the item since this is a vertical grid you know the the vertical constraint is basically the same as the parent right it could just be as big as it needs to be but we want to say that the item can only be as big as the column width that we've defined so the way we can do that is say the item specific constraints are the constraints that we have copy them change the max width to column width so this is how we make sure that none of the items are you know wider than we've allowed for our columns and so now we also need to keep track of um it looks like they call this column heights and they want to say like for each of the columns that we have we need to think about um whoops how big that column is going to be so like if we have like two like our staggered thing has two items in it two columns you think about how big is each one going to be and the only way to do that is to first like measure everything that's going to go into that column so how are we going to do that well let's create like an integer array of those heights for each column and we're going to start them off with default values then we're going to measure our columns and populate those values don't know if that makes a ton of sense let's type it out let's see if it follows after so column heights we're going to start with an inter array we need to keep track of the height for each of our columns so it'll basically num columns right and then we can actually use a lambda to give all of these a default value of 0. so maybe i'll write some documentation here um so per column based on constraints um make sure items can't be wider than column width and then track the height of each column in an array okay so we've got this default value of column heights and now we can get all the children that we need to place so let's keep track of our placeables which is measurables.map um so this is actually good this is i have to write a separate method here let's type out the google thing and then we'll talk about it so our column is going to be um interesting it calls shortest column from column heights let's look at this and then we get a placeable measurable.measure item constraints and then sorry i'm writing all this out so i can understand it because i didn't read it all so to get our list of children we go through all of our content we start by determining the shortest column um interesting ah i understand how this works okay so let's think about um how we lay things out so let's how do i do this i feel like i i need a picture i need a picture to describe what we just did here let's look at the staggered grid yeah okay we can i guess i wish is that one of like column two um all right let's look at this one and let's just kind of talk about uh something we need to think about so let's think about like we have this list of items to place in our staggered grid so it might seem at face value that what we're going to do is place one in the left column one in the right column one in the left column one in the right column it feels like that might be what happens but if we actually look at this gif if we look when it scrolls down at the right you can see that like in some spots um i clicked on it i didn't mean to there's like three items here that are the size of one and so that's a trick that we want to do right we want to figure out of the columns that are populated which one is the shortest which one has filled the least amount of space whichever one is shortest that's where our next item needs to start so now that we've thought about it that way that we're not just placing left to right but we're determining which column is the shortest which is where our next item needs to go that's what we do here so we go through each item then we look at our columns and we say which column is the shortest and then based on that we will measure out the item based on their item constraints and then the item that we just measured we're going to add that to the column heights of the column that we're adding it to and then we're going to return this item so we're not actually placing it yet what we're doing is going through and figuring out which column it belongs to adjusting that column height and then we'll go from there but to satisfy the ide let's talk about how we calculate shortest column so let's pull it up um and it's really just kind of a look up uh shortest column we give it like a list of all of our heights which will be an ins array and it's going to return what that shortest column is so the way we can do that um i'm just going to copy that code here um we say the minimum height is max value i'm surprised they went with that and then the column that is the shortest we're going to default to zero so let's go through our column heights for each indexed so we've got our index and our height and we're going to say if height is less than min height i see so we start with the min height being really high and then anything lower than that we'll pass so if the height of the column we're looking at is lower than our minimum height we're going to update what that min height is and then the column is going to be this index and then we'll return that index i'm going to rename that to make that a little more clear column index is what we return so this is just a lookup we've got a list of our columns how big they are we're going to find the smallest one i feel like we could play some code golf on this method and make it smaller but i'll come back to that okay so now we've got our list of things to place this is actually going quite fast um and i hope i haven't lost any of you but again i always like repeat this code like five times over after i write it all i talk through it as i'm writing it and then i read through it again hopefully it helps um but we're actually pretty close so um oh man let's okay let's talk about this one i'm gonna copy this from the google code um and we're gonna talk about what this is doing because i'm a little confused here um okay i think i understand so what we need to do now that we have all of the items we need to place is we need to figure out what the height the total height of our grid is going to be so one way to look at that okay is going to be like look at all of our column heights and find like the max height we've got this list of columns find which column is the largest i don't know why they use max or null um oh god did i freeze my ide i was trying to command click and to see what that did and i've frozen my ide oh no um can y'all still hear me am i frozen or is it just the ide that's frozen it looks like it's just the ide um okay i guess it's assuming that you know it's possible that column heights could be empty but this feels like i'm gonna go ahead and say that this could never happen um because we're forcing i mean i'm gonna say that this can never happen but i suppose it could oh is that because max is deprecated that might be why maybe it just uh doesn't want you to do max anymore maybe it wants you to consider null and then it looks like this coerce and i think what this is trying to do is say that you know once you've measured the columns we have to ensure that it's both bigger than what our minimum height of the composable is but also that's smaller than the max height and i think what coercin will do is um if it's too small um it will round up to the minimum height and if it's too big it will round down to the max height so let's look at that dock just to make sure that is indeed what is happening um yeah so gotta run for a meeting yeah thanks for stopping by i will this will be posted that it'll get put up to youtube i will also share the code with you or i believe it's been dropped in in them in here as well let me actually put it one more time for you um yeah okay so we get our largest column we ensure that it doesn't break the bounds of what we're trying to fill oh i should do that i don't have an exclamation point youtube command i am a terrible content creator but i will do that i will follow up on that um we ensure that it's not within these bounds and then if for some reason we can't find anything then we will use the minimum height of our constraints tick-tock coming soon maybe okay so we went through we measured all of our items we calculated the height of each of our columns we figured the height of our staggered grid as a whole um the last thing we need to do then is to actually like lay out the content so let's do that so we're going to call layout width will be as big as we can be we want our grid to fill this whole space here but the height is going to be the height that we just calculated and then this is the lambda so let's see what do we do here got it so let's before i write this um let's again talk through how we place items so if you remember when we looked at this sample code right here for how compose works with just a standard column a single row it keeps track of this y position it starts at zero we're gonna place an item and then we're gonna move our y pointer down whatever the height of that item was now when we think about laying out our staggered grid it's going to be the same idea but we're going to want a pointer for each of our columns okay so let's start there we're going to keep track we'll call it column y pointers this will be an end array for the number of our columns and we're going to start them all at zero okay then we're going to go through each of the things that we need to place now let's um let's talk through this so we have content that we want to place okay the column that we want to place it in is whatever our shortest column is and then our column based on our y pointers so we've got these list of columns we've got all these pointers right we need to find which column has like the lowest pointer so they all start at zero but when i place something in column one the next time it'll be column two because column two will still be at zero and think about it that way or whatever it may be we're gonna find the shortest column based on the pointers that we have and then we're going to take the item and we're going to place it on the screen the x value is going to be so the x value is where the item starts when we think about it it's whatever the width of our column is times what column we're in so let me type it and then let me say that so if we're in column zero whoops nope that's not what i want i want column width times the column so let's think about this if we're in column zero this will basically be column width times zero so it'll start at zero at the left if we're in you know column one which is the second column zero indexed we're going to take our column width times one so it's basically going to put it at the start of that next column and you can see that because we're timing it will just shift so this is how we figure out the x value hello sir diesel thank you for stopping by and then our y value is going to be um column y pointers for this column let me double check that i did that right yes so that is how we place the item and then the last thing we need to do is take that pointer for the column that we just manipulated and we're going to add the height of the item we just laid out so let's say this out loud again we're going to lay out all of our items we've got pointers for where we are in each of our columns and then we're going to go through everything that we need to place we're going to figure out the shortest column that it needs to go into then we're going to place that calculating the x and y and then because we've placed a new item we need to move our y pointer for that column down to wherever this item is done it's a little hard to visualize maybe it would be very cool to i would love to learn animations because i actually feel like after talking through this i've really grasped this in a way that i didn't like five hours ago um but i don't know if i've done the same for y'all but i think it would be really cool to like learn some animations to demonstrate it but if you have learned something let's um let's run this and see if we were able to do what we wanted to do so let's um let's go to text card list and where we have this lazy column let's uh just comment that out for now and let's write out our staggered vertical grid so we're going to create a staggered vertical grid um i want to go ahead and do something like um i'm going to give this padding just so our grid is like not running up against the edges of the screen um i don't think it will have space like above each item but that could be a cool follow-up let's just make sure we get the staggered part working um and so now we need to give it the content and the way we can do that is we can basically take our texts and go through each of them and for each one we're going to add a text card with that text let's just do that okay staggered vertical grid this is our modifier um behind the scenes you know we had a numb columns we're going to also say 2 but that's what it is and then we're going to loop through and add each of our text um very cool moment of truth let's see if we did it uh that would be quite an impressive speed run to have built that in less than 45 minutes i did not expect that ah it worked um it does not have the spacing between the cards like i mentioned but it worked ah that's so cool um you can see it's definitely like again the cards blur together because we're not doing spacing but you can see that it's it's staggered that's definitely staggered wow all right so hmm well the first thing we're going to do is commit our code so we don't lose that completing staggered vertical grid staggerness has been achieved indeed um uh yeah we we can go a little further and try to talk through like how to make this like look right you know actually i should um one thing i love dark theme don't get me wrong um the thing that i don't love about it is like by default card views they're really hard to see like um against the black background it's hard to see what's like a card and what's not um i guess that's actually even more true in light theme um all right i made this worse i thought i was gonna get better contrast for the cards and i did not so you know what we can do we can go and um let's go inside our text card composable real quick um can we set a color content we can set a background color and let's just make our cards like an obnoxious red so yeah i think that's part of it like the shadows are being hidden um i can see like where they're at but it might be hard for you yeah and again so now it's a little more clear where the cards are but you're right there's no spacing in between them so this is a good question how do we how do we do this how do we set that spacing one thing i would start by looking at actually is um i want to look at the code for a lazy column and let me show you why i want to look there so the lazy column it has this vertical arrangement where you can they don't show it here but you can pass in like a spacing for each of the items um so i want to click through to see if maybe i can see how oh god this is going to be really confusing um vertical arrangement ah it's so lazy i just want to see i just want to see how they use this okay so they do some weird like arranged stuff here i don't even know what we're looking at now um all right i'm not going to go down that rabbit hole um so let's look at our staggered vertical grid and let's see if we can um think about it so one way i think we could do this is um this line that happened to be highlighted right here so every time let's just kind of talk out loud here every time we place an item we have our y pointer and we move it down the height of the item we just placed but what if we also wanted to then supply like a height like an additional space like between the items like what if here i want to do this and then do plus you know 12 dp will that work here i don't think i can do that no um i wish i knew like what to um maybe she knew how to convert like a dp the height here um but like that's what i'm thinking is like right here where i move my pointer i can then also um add it out um like one like a hacky solution that you might do today with like a recycler view is if we go to our list like or well on like the text card i have seen stuff like this where like i wonder if i put i could put padding on the card which is like a little hacky but it would probably create the space i want but instead of putting it on the card i would want the yeah that worked um but i don't want to put it on the card i want the the grid to do it so how do we how do we do that uh um ooh um now i was thinking about like putting like a spacer but i don't think that will do it um maybe though um there's also so compose also has a lazy vertical grid which is another thing i looked at um i feel like that would just add um oh no that's not what i want either all right um i don't know maybe i don't know maybe i can't i can't do that i'm sure there's a way um there's got to be a way but like is there something i could do on the measurable um it does feel a little more tricky doesn't it um like there's probably something silly but i don't know off the top of my head let's look at the constraints class what does that give us so we have constraints they have min width max width min height max height do they have padding or anything on here um no i guess they don't have like you're padding um i don't know i don't think i know enough to figure that out um without going down that rabbit hole of um like wherever i was looking at the um that equals this what is this measurism measure scope hmm so can i type something in here like yeah i don't know um all right i think we're not gonna go down that rabbit hole um but maybe what we can do for now uh just to like have something that looks cool is put some padding on the card let's go back to where we put our list um get rid of that and let's just put the padding on the card and let's see what that looks like um maybe that'll be good enough for now just to prove it works yeah all right that's not again not like super great but oh this doesn't scroll that's buggy um let me add more items real quick just to make sure that that's something that also makes sense that it doesn't scroll because i never did anything with a scrolling modifier so um does this google one i don't think so um interesting okay okay so this doesn't scroll um an interesting way that uh oh wait um oh never mind um why are you running it with a debugger that's just a habit that's what i always run things with um okay the way that uh the google one did this is really interesting they basically just took it in they just wrapped it in a column uh and then just gave it like a vertical scroll i have so this is feels kind of hacky but uh this is how like the google sample did it and i guess this is a quick way to take something you wrote and make it scrollable another thing that uh our sample app doesn't do yet now it scrolls another thing this doesn't do is um it doesn't words it doesn't recycle so it's not like a lazy staggered grin so if you had a bunch of items it would place them all uh i think that's fine for these the purposes of this sample but uh something to keep in mind i do want to go back now and actually look at um the owl sample and i want to see there i wish i could pause it so they have spacing which is interesting when i was writing this i didn't see any um spacing on the vertical grid um so i'm actually gonna look at maybe they do something um on the interesting okay so i'm looking at the oh i should have done it on this screen um let's go back so if we look at the google one um if you look at their featured course composable um it looks like they take each course they put it on a surface that has a 4dp padding so that's how it's able to get the the spacing between each item um is that it yeah so i guess that's not terribly different than um what i'm doing with the card but i think that four looks a lot nicer than 12 so let's let's change that real quick um and then here oops nope here we can do um change the padding um nope not here on this one we can put four here as well and that should give us a little nicer padding um it's a little weird to put the padding on the individual items i feel like it would be cool to make the grid do that um but i'd have to do some research on how to make that work this looks a lot nicer now um sorry let me catch up on chat without fixed height would it even be possible to have a staggered grid how would you know how to place them if you don't know how they are all the way to the top that's a good question um you're right maybe you don't um but then i'm curious how i think for a staggered point yeah that's tricky to do um there is like a lazy grid if you want just two things side by side um that we showed in the very beginning of the stream i don't know if you were here but basically what that what a lazy grin is is each it's basically just a lazy column and each row has more than one item in it so just places two things side by side and like that's how it like is able to recycle everything um be right yeah maybe this would be hard to do lazily um yeah all right that's cool uh let's see is there anything that um i don't know if bo is still here and maybe we could try playing around with gestures oh one more thing i want to try before i move on is i just want to bump the number of columns i'll also bump the number of items um i just want to see what uh what this looks like if we have like three columns okay that still works pretty good um yo vape juice jordan thank you for the follow what a what a handle i'm gonna update this to like 100 items why am i being lazy let's see what a really long list looks like um oh thank you for the follow as well silent matthew appreciate it this looks cool nonetheless still in my head time wrap my head around lay up manual placement it's it's interesting for sure yeah it definitely is i think um yeah this looks really good um i think after having done this and i'm obviously speaking i guess from unlucky places that i was able to do this nice and slow i feel a lot better after doing it today and the handle is great i love it you should wear it with pride it's not often you have a handle that uh gets like streamers so excited 20 columns let's do it let's see what it looks like it probably will break at 20 but i bet we could get like five and have something kind of decent um i mean it worked it worked we got something out of the matrix but it worked still still out of the matrix but i'm going to need to update the color of the green here but yeah no that i mean at least we know it works really nicely um let's change it back to like four let's see if four looks decent on the phone um this is cooler than what i expected yeah uh oh so sorry i got a little distracted but um let me commit this code before i got it playing around with padding um but i want to answer like your thought about like manual placement is hard um and here's my thoughts on that like i agree i agree i think that it's tricky and i think the reason it's tricky and maybe i'm projecting here's my reason why i find it tricky is it's because i never have to do it right like we're very fortunate to have layouts that do it for us even in the existing ui framework right you have your linear layout new of your constraint layout which you kind of place things yourself but you really just like related to the container and you let the system do the nitty-gritty of like figuring out what those x and y values are and then even in other things in compose you have like compose has a constraint layout but you have rows and columns that like just do it but after having looked at this myself after going through this layout and talking about it out loud i found that the explanation like like breaking it down really small it made sense to me like the idea that you keep a pointer that starts at the top and every time you place an item you move the pointer down and it sounds tricky again because we never have to do that but breaking it down to that actual step helps me understand what this does a lot and i think that actually makes me inspired to try like more custom layouts now that i can think about that a little more and i think this was actually a even for that a little bit of a complicated example because we were dealing with columns and we had a little bit of math going on like we did the math to coerce the height we had to do we had a raise of pointers and it's hard to understand those um explaining stuff was my superpower and how i learned most things yes um it's a huge reason i love making content and giving talks and writing blog posts is t uh learning through teaching is huge like if you need to teach something then you need to learn it yourself and on the flip side i think having just learned something makes you a really good teacher on the topic i bring this up a lot and that's because if you're new to a tool you're going to experience roadblocks and barriers of entry that you can help people overcome and when you've dealt with the tool for a really long time you forget about those roadblocks like you've seen them you learn how to work around them and so now you just know how it works and that's good you can then start to give like a deeper dive into things but i find like certain things in my experience i have trouble explaining them to like beginners because i see them run into issues that i ran into when i was starting and i forgot like there are things i take for granted now um so i think like when you just learn something new it's like the best time to share it with other people because you've got all those roadblocks and challenges fresh in your head and it helps solidify what you're learning so like that's something i should take a lesson from that myself and like learning how to lay out custom things and really like thinking through it step by step would be another great opportunity for a blog post but i guess even this is doing what i just said i'm learning it with all of you that's why i really like doing these coding streams um i know they're hard to follow along because like if you they're hard to like leave and come back but i think they help a lot ah the shortest column method again yes so um this is truly just um like a lookup we have this integer array and we want to go through each of them and find the smallest one and then return that index so the way we do that we start by setting this min height that's like super big right and then we can ensure every item is going to be lower or like the first item will be so then we go through each of the index we check the height so this actually if we now that we've built it i said that there would be an opportunity for code golf here and let me show you what i mean by that kotlin is ridiculously powerful and that i'm pretty sure i could do column heights and then i could do um can i get like index of um thought there would be a way to find like the index of the minimum one um but maybe not maybe that's another maybe a line collin has some really good like filtering and searching algorithms that i thought you could find like the index of the the minimum one without writing this this check yourself but maybe it wasn't built in i suppose it's because we need to know the index of the minimum if we just wanted min we could just do like column heights dot min or null uh which is something we did like before um but that won't give me like the index of it you know so i think that's why we have to loop through it ourselves so we can keep track of the index of the lowest one um yeah i hope that was helpful do you want me to i don't know if you heard in the beginning i don't know if i should run through this again after talking about it step by step um maybe we could continue with the documentation let's do that let's walk through it again and then i can also continue with these small bits of documentation so the first thing we do is using our number of columns that are max width max width we figure out what the width of each column will be we ensure that each item can't be wider than the column width we track the height of each column in an array um then we could say for each item to place figure out the shortest column so we know where to place it and keep track of how large that column is going to be um so that's what this does this loops through each item figures out the shortest column that we have measures the item and then updates that column height based on the item we just measured so now we get the height of the entire container grid and ensuring that it does not um go out of the bounds of this container or we'll call it a container so we do that by getting our largest column um here by using the largest column and then we ensure that it does not go out of the bounds of this container so that's what coercing does um if something went wrong default to min height okay and then now we lay out all of the children um whoops so i'm not even gonna comment there um keep track of the current y position for each column um and then here we get determine which column to place this item in place the item and then update the pointer for this column based on the item we just placed something like this could work feels like we're doing a dance though instead of making it simpler i don't know column lines.map indexed min buyer null yeah i see what you're doing there so you're converting it to like a map of like the index and the height and then you're sorting the map it's the same idea i don't know if it i actually don't know if that makes it simpler but code golf is fun it's definitely probably fewer lines um okay yeah i like this documentation i'm gonna push that um and actually we'll add some documentation on here so loop through all of the column heights and determine which one is the shortest no yeah i could put it in there i definitely see what you're saying maybe i'll put it in there for uh people who are reading to see it uh let me do that in a second um this is how we determine which column to add the next item to um yeah let's try it we can do that real fast um oh god oh it's because it's two yeah so take the heights create a map where it's index to value and then we find the minimum y value and then if we have something we take the index otherwise we return zero it's the same idea um i suppose yes definitely fewer lines than above and like i have i've mixed feelings about these i think that people who are kotlin gurus can understand it i think that um it might just depend if someone's not super familiar with all these operators on maps i don't know if it's super readable um and like that's that's one of the problems of code golf and i do this too is like it's fun until you look at it and then they're like would my teammates understand this um and i don't know like sometimes that's not always the case sometimes i think like you should go with what you think everyone can understand um i also don't know i'd be curious to like performance test this like would this be faster like because we're we're mapping it and then we're searching for a minimum versus this is just doing that sequential minimum search um so like it might even be like faster to just do the sequential search that we're doing but thanks for trying it out though i'm always down to explore kotlin i really appreciate that all right anything in twitch chat that uh we could keep it to a short stream which is always good when i post these things back up to youtube so um maybe we'll wrap up unless uh unless chad has some other things that y'all want to look into um bo i don't think they're still here but they had a great idea in the beginning of the stream which is they want to know how to remove an item from a list maybe like a swipe to dismiss sort of thing and i have no idea how to do that but i think that that can be our plan for next week's stream which usually on wednesdays by the way today is an outlier um though i would like to start streaming more so who knows maybe thursdays can be a thing more often but don't forget to don't forget to start the repo check out all the code we just wrote um usually it should be slower in my bachelor's thesis happened do something like this here the cat in idiomatic way was always slower yeah that's an interesting thing um i think that i've seen i'll i'll click that link real quick but yeah um oh that's well uh i'll check this out though i think that it's definitely um an interesting question like the column idiomatic way um it looks cool and sometimes i think that's it i think it just looks cool i don't always know if there's more to it um but yeah thanks for sharing that thanks everyone who came by tonight i appreciate it um i think that we'll uh i think we'll keep it to a short stream we did what we wanted to do we built a staggered grid um i think what i'm gonna do is um do i to leave it as red i kind of want to change that to a different color so i can get a cool gift to post on twitter but i'll do that after um but yeah that was i hope you all learned something uh let me know in chat if you have any questions or if you're not following me on twitter uh please do you can always reach out to me there and i'm happy to walk through some of this do i not have it there uh what about social i thought i had i thought i had a command for this uh whatever um my twitter handle is the same as my twitch handle so y'all can find it although if you're here you probably did follow me on twitter first so yeah thanks for stopping by thanks again for following i usually stream every wednesday around this time hoping to pick up more more stream slots sometimes but wednesday's for sure you can usually find us here so thanks everyone have a good night
Info
Channel: Adam McNeilly
Views: 873
Rating: undefined out of 5
Keywords: games, twitch
Id: 0xJdjX5NWKU
Channel Id: undefined
Length: 73min 6sec (4386 seconds)
Published: Fri May 21 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.