Adaptive Layouts (The Boring Flutter Development Show, Ep. 45)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
FILIP: Hello, everyone. And welcome back to "The Boring Show." It's been a while. I'm here with Fitz. FITZ: Hey. FILIP: Hello, Fitz. FITZ: Hello, Filip. Good to see you again. FILIP: Yeah, good to see you, yeah. And by here, I mean, we're obviously not in the same room, but-- but whatever. It looks like it. In post-production, they will put us in the same room, I'm sure. OK, today we are going to talk about adaptive design. There-- what I mean by that-- there's many definitions of it, but basically, it means I have an app. I want it to look a certain way on a mobile phone and a certain way on a tablet and a certain way on a PC. And for that, I actually thought maybe we don't want to go with-- we normally, usually use the Hacker News app. FITZ: Mm-hm. FILIP: And that's-- that's great, but I think-- I couldn't imagine how to make it work or what to show exactly in the Hacker News app because what people generally mean by the adaptive thing is, I want, like, a list view and then-- like, on a phone, I want a list view first and you click and you go into a detail page. But on a tablet or a computer screen, I want that panel on the left all the time there and then just clicking through changes my view on the right. FITZ: Right. Yeah. FILIP: And-- and so that doesn't-- like, I couldn't figure out any way to do it on Hacker News. I mean, like-- FITZ: Yeah, you could maybe envision, like, I don't know, the list of the articles on the one side and then the body of the article or maybe-- FILIP: The body, yeah. FITZ: --the comments or something on the main view? FILIP: No, you're right. The body would make sense, but that's like-- that's-- that's a view of basically, a website-- well, anyway. So we'll-- we'll try and I started something from scratch and we'll see if that works. Another thing that we're doing completely new is we're not-- like, I'm not sharing my screen with Fitz. He's actually in my code right now-- [LAUGHS]---- and you can do anything. FITZ: It's a wild bit of technology that has come about with everything being remote. We're trying to-- we're sharing an IDE remotely, and so we'll see how it works. But we both can control the cursor at the same time, so hopefully, we don't mess each other up. But it's paired programming, and this is what "The Boring Show" is about, so we're going to give a shot and see how it goes. FILIP: Absolutely, yes. And I'm glad that this works we. Absolutely installed it just today. We have zero experience with it, so we'll see how it goes. All right, so first thing I want to show you is my little trick when you start a new project in Flutter and you see all these very important comments in the code and you don't want them there. And you could do many things, but what I do is I just replace-- search and replace using regex, like this-- and I just Replace All and then I format everything and I'm done. So I just replaced all the comments there and the regexp is very like it's just //.* So once you do this enough times, it's-- you don't mind the comments. FITZ: That's a nice little trick. I think my tactic for that is I go to the MyApp and I just delete it all and then I start from a new stateless app-- stateless widget, which is kind of like starting from a blank main, but, you know. At least some-- FILIP: No, no. This is good. I realize now that-- yeah, I'm kind of-- I would have to remember like material app and stuff like this, which I should, but, anyway. All right, so now-- one thing that I kind of did beforehand is that I found a generator of JSONs, like a lorem ipsum JSON, I think it's called-- which gives you some random, like, completely random made-up data that you can play with. And so what I thought today would be pretty easy to do is to have an app that just shows some data, like structured data. What I see here is-- it's a list of people with their names and there is a bunch of little pieces of information about them. And so we could have that list of people as just, like, tapping on their name. And then if you tap on that name on-- let's do the mobile phone first-- we show some random data for them and then we're done. FITZ: So it's kind of like a contact app in some ways? FILIP: Yeah, yeah. Yeah. FITZ: Nice. Let's do it. FILIP: All right. So let's just remove all this. I just realized I have zero, like-- zero state management. Well, we'll see. All right, so start removing stuff-- column. We don't need the counter. Do you see all this, by the way? FITZ: It's a little delayed, but I do see it. FILIP: OK, good. And then we have the children. All right. I'm going to create the people-- I am having second guesses about starting from scratch. [LAUGHS] But we'll see. All right. FITZ: Yeah, I think it's-- with whatever-- wherever we take this particular episode, I think it's a good lesson in general. When you're designing a real app, it's helpful to think about these things as early as possible. Maybe not necessarily from the start of writing your app, but as early as possible. FILIP: Yes. FITZ: Because you don't know what size your-- device your users are going to have. And so, like, we might test on a mobile phone emulator. We might test on a tablet. We might test on with a desktop window or whatever it happens to be. But your users are going to be on a different size, so it's really helpful to think about the overall presentation and layout of your app and how it's going to adapt to the different sizes as you go about. A long time ago, I heard a bit of advice from a designer that was saying, one thing-- and this goes for testability as well as adaptivity-- is look at your device and design for the smallest screen possible and then design it again for the largest screen possible. And sometimes things in between can, you know, they'll be a little bit different. But as a great start to think about is when you compress it down to like this tiny little box, what does that look like versus when you have as much real estate as possible on one of those, like, giant 50-inch curved weird things, right? What does that look like versus the smallest? And so, I think even if when we, today, decide that there's a lot of set up that has to go into an adaptive app that is not about app adaptivity or responsiveness then I think it's still a good lesson to know that checking this out and thinking about it and working on it from the beginning is really, really helpful. So, Filip, where have you ended up? I am kind of following along but-- FILIP: Yes, so I-- thank you for covering for me because I've, in the meantime, hopefully, created some kind of a data class of the people that we'll be showing. And so let's see if we can actually use it here. So that would be-- I use final, but to be honest, var person in people, making sure that we import it. And for each of them, we'll just do-- let's do a list style. This should be a list, and not a column. ListView-- FITZ: OK, so you're having the primary view of the app right now is going to be a list of the people in our contacts JSON? FILIP: Yes. FITZ: Cool deal. So it's starting to get towards our idea of one of the easiest assemblies of an app is the main-- the list of something and then the detail of the items in that list on the one side, so I think-- FILIP: So one-- FITZ: Yeah, go ahead. FILIP: Go ahead. We have this, which is great. I kind of want to add a picture of the person. FITZ: Hm. As, like, the leading image or something? FILIP: Yes, yes. So there will be image network. And I think this even gives us a picture. Yes. Oh, well. We could just grab this. To be honest, I think it's the same for everyone. FITZ: Oh, yeah. So in reality, you'd want to get the value of the picture key, but we're just doing the URL direct? FILIP: Ah, you know what? Let's do it right. So string picture and this picture and e picture. FITZ: Cool. FILIP: Generally, you would want to have something more clever here, but-- person-- than-- than me-- like, I don't want to parse the whole JSON by-- FITZ: Oh. FILIP: The URL is not null. It's not true. Interesting. FITZ: Hm. FILIP: Oh, is this because-- yeah, OK. That's it. Really? That's kind of sad. OK. It just says 32 by 32. FITZ: OK. FILIP: I thought it would be, like, a picture of someone. All right. FITZ: OK. FILIP: All right. So we have this. And now we probably want people to be able to go to the-- to the-- detail. So we need a detail widget. And for that, I'm just going to do, like, a very simple class, PersonDetail. FITZ: OK. FILIP: And that's because it needs the Scaffold because it-- wait. Hm. FITZ: So that's a good question, and I think this was something I was thinking about when we were talking about ahead of time is, how do you structure these different widgets differently when one is a new page or a new view versus one that's going to come up alongside of it? FILIP: Yeah. FITZ: And I don't know the answer to that, but it's something we should talk about. So-- so what-- I guess the first thing would be, like, what does a scaffold do and why do we-- why would we want to have this detail widget have its own scaffold? FILIP: That's-- OK. So, yeah, very good point. We generally-- the scaffold is just things that make an app have the, like, the chrome. So, for example, the ad bar is part of the scaffold. If we had to draw the right, like, it would be part of the scaffold. Anything that kind of overlaps the body of the app from each side, that's the scaffold. It also gives us the ability to show-- what-- what do you call them, task? No. Toast? FITZ: The snack bars? FILIP: Snack bars. Yes, thank you. FITZ: Or the floating action button. FILIP: So all that we need-- if we have a separate, like, on a mobile phone, we have a separate screen. We need a scaffold most of the time. And we will need it when we want this on the mobile phone, but we don't want that for desktop when we have that widget just sitting next to the list, right? FITZ: Yeah. FILIP: So on-- just to be clear, so on a phone that's going to be like this and I click here and then I go into the detail, on a tablet or on a desktop, we would have that detail over here in this area, and so we don't want-- we don't want that to have its own chrome and its own, like, app feel. FITZ: Yeah. There are cases where nested scaffolds are useful. This may not be one of them. FILIP: Yes. So you know what? I think I will make the person detail pure, right? So this is something, by the way, if you're coming from Android, you may be familiar with fragments. And these were a similar idea of, like, a fragment can be either this-- either on its own, or it could be put as an iframe, another thing that could be put together to make a panel basically. And in Flutter, we don't have that because we don't need that because everything on the screen is a widget. So we can just make a column and that can be one-- one part of the column can be one fragment. It's just the widget. And the other part of the column is another-- or a row or whatever. So what I'll do is-- on a whim, I'm just going to do the PersonDetail like completely pure, and that means I'll just do a column again, I guess. Let's start with that. And that will have some children. And the first one will be the name of the person, which implies that we need the actual person here. Person-- and, of course, PersonDetail takes the person. Person name-- very exciting widget-- text person phone. So we show something new. FITZ: This is a really nice widget. I like-- I like columns with just two text fields. They're my favorite widgets. FILIP: [LAUGHS] Yes, yes. You're a minimalist. FITZ: Yeah. FILIP: It's what I call it. All right, so let's see what happens, actually, if we just use that pure widget so that you understand the value of scaffold, y'all out there. So onTap, we're just going to do-- we're just going to Navigator of context can write push route and that's going to be a MaterialPageRoute. And that's going to be a builder. And now I don't remember what that builder takes. FITZ: Um, I think it takes a context, right? FILIP: Oh, just the context. Cool. So just context. And we are going to do the PersonDetail with a person. Everything works as we'd expect. So now if I tap-- I just realized you can see it, Fitz. You can see the app. It's-- it's great. FITZ: Sorry, but-- The benefit of a minimalist design is that it's relatively easy to imagine what it looks like. FILIP: Yes, yes. Yeah, so I'm clicking on Clemons Waters, and I get this terrible black screen with his name and his phone number. And-- but it's underlined by yellow lines and it's all red. It's just the usual stuff when you try to show something without a scaffold or without even a material widget. So-- so it works. It works, but not pretty. So for that we can just-- which we can literally, just here, in the MaterialPageRoute, we can do Scaffold here. And this can be the body of the scaffold. Oh, no. FITZ: Right. So then-- doing this-- doing it this way, where we have a scaffold in the MaterialPageRoute, we can make sure that the PersonDetail widget is still only responsible for rendering and building the details of a people-- of a person. They don't-- it's not worried about the scaffold. It's not worried about the theming. It's not worried about anything else, only person details. And then our page route can handle the scaffold. FILIP: Correct, yes. And I do want to do that. I want it to center it. Now, we could do a bunch of things. We could even, kind of, inject to the person detail, like, the context as in, we could say, hey person detail-- here's the person and-- and here's what I want you to do. You should draw yourself as if you are your own widget. You know, like we could definitely have an if-else statement here, and it could be something like if standalone then add the scaffold. And-- and because I can imagine, for example, if you have a standalone page, you might want to have the name of the person in the ad bar, right? And-- and I don't-- I'm not sure if you want to have that here in the homepage state. We might want to have, like, the PersonDetail then go somewhere else. Or we can have a different widget altogether. But I think it kind of works now. If I go, again, here-- why am I not seeing it? Wow. I did something wrong? Apparently. Oh, I know what. This should be mainAxisAlignment is-- FITZ: Ah. FILIP: --uh, not alignment. Axis alignment center. And now, a beautiful page with just Clemons Waters, name, and his phone number. And no way to go back. We could add at least that. All right. So, so far, so good, I think. FITZ: Yeah, so this app bar you're adding in-- FILIP: Mm-hm. FITZ: --um-- FILIP: It is just there so that we can go back in a way that is app-y. FITZ: Right. OK. Makes sense. FILIP: Yes. So all it does is it adds this app bar here, the blue one that you don't see, and-- and it has the Back button added intelligently because it knows that this a route to go back to. All right, so-- so this was all-- we've just done the easy part. The one way to display it. And now what if we want to do the-- the other one, the more-- you know, everything is on one-- in one place. Now, how do we-- how do we want to start with that? So-- so first of all, I guess, the important part is we have a widget for this. It's called-- well, we have two different ways to do this. One of them is media query, which is when you are asking, as a whole, the app-- what does it look like? Is it-- is it a big screen? Is it a small screen? And so on and so on and so forth. LayoutBuilder is more context-sensitive. Like, if you run a LayoutBuilder in a small modal window, it doesn't know where-- if everything around it's like, is a huge space. It just gives you the layout that is currently where it is currently in, right? I think it makes more sense because at some point, we might-- I could imagine that even this that we're going to write this kind of list detail, split-- is part of a larger whole that is even larger. And maybe at some point, we want to say, OK so we don't have the space for-- even though we are on a 4K monitor-- we don't have the space to do that thing. So we want to use the LayoutBuilder. And now-- where do we put it? FITZ: That's why I just pulled up the LayoutBuilder documentation. Um-- looks like it needs to be pretty high in the widget tree. But the samples, at least, have it underneath the scaffold as the first thing underneath that, as the body. FILIP: OK. OK. So let's do that. FITZ: Start there. The builder that it takes-- the two parameters it requires are the context and the constraints. FILIP: OK. And from the constraints, if I understand correctly, we'll get the size, right? FITZ: Right. Yeah. It's a box constraint, so that'll give us the height and the width. FILIP: Great. This is exactly what we want. So LayoutBuilder is a, conceptually, I think, a pretty simple widget. It just rebuilds any time the layout around it changes. So any time, for example, you switch the orientation of your screen, that changes the layout. That changes the constraints of the whole app, basically, for us, and therefore we will-- we will rerun-- or this builder will be rerun with a new context, or the same context, probably, and new constraints. And you can use it in many different ways. It's not just for adaptive things. It could be that-- I don't know, we want to have a red app bar if you're like this, or-- I don't know. But for-- in our way, in our-- for us, we do this. And I think the cleanest possible way to do it would be to just say something like if constraints-- if I can write constraints-- and you have a lot of different-- again, you don't see it, right? FITZ: Correct. FILIP: Do you see it? FITZ: I see-- I see the code, not your-- FILIP: Right. So-- so we have a lot of little fields on constraints, like hasInfiniteWidth, isNormalized, isTight-- I have no idea what that means. It also has the biggest, which is the size-- if we use the whole screen, kind of, or the whole area, like, what is the size of that? So I think we'll use that as a size. I mean, as-- oh, there's maxHeight and maxWidth, minHeight, minWidth. All right. So the easiest thing is probably if the width is above some threshold-- so if maxWidth is more than-- I have no idea, 400? I'd have to test this. Then return-- mm-- DesktopLayout? Or, no-- WideLayout. FITZ: Um, so these-- this notion of setting these effectively hard-coded width sizes-- this notion is something called breakpoints in other contexts for responsive design. And these are just commonly accepted approximations for what constitutes wide layouts versus narrow layouts. And so, there's no-- so you, as your app designer can decide what that actually-- what those values actually are, what makes sense for your data. Since we're doing a fairly typical list detail layout, this is pretty common, so we can use pretty common values. And 400 is approximately the difference between a mobile and something else. FILIP: Right. Hopefully, I don't-- let's test it. FITZ: We can also see how it looks and then change them. FILIP: Yes, exactly. So as a terrible hack, I will just return NarrowLayout from WideLayout for now, except I will repeat with something like Container. I just want to see when the breakpoint kicks in. So color-- color's red. Probably-- yeah, OK. So we're now already in the wide layout. So let me change this to 500. OK, so about 500 devices-- we're always talking in-- we're always talking about device-independent pixels. So this is basically like a measure, like, in centimeters. It should be very similar on all screens, and it doesn't care about your resolution. It cares about the physical size of the screen. And so I think-- I would even maybe make it-- make it 600, if 400 was too small. And now, if I remember correctly, I can rotate the device like this and see if I retweeted the device-- again, Fitz can't see it but you can. [LAUGHTER] As I rotate it, then this is the WideLayout with the red background. This is the NarrowLayout with a white background. So we-- we're already there. This is, like, the adaptive thing, right? We're adapting our screen or our app somehow to a wide layout. And-- and so, OK, so we're just-- I think I'm just going to-- there is probably a better way. Is there a better way to do it than to just copy-paste this and make a new one? FITZ: Um, I mean, we-- if we could factor out the ListView into its own widget-- FILIP: Yeah. FITZ: --that would be helpful because then our narrow layout-- each one of our layouts only needs to say, here's where the ListView goes. Here's where the DetailView goes. FILIP: Right. And then it just basically there needs to be some callback where the white layout says just change this, and the narrow layout says, push this. Yeah, OK. I like that. FITZ: Yep. FILIP: OK, so this would be-- naming is hard, Fitz. What-- what's it-- what's the widget called? FITZ: Uh, PeopleList. FILIP: PeopleList-- list of people. And that just-- ListView doesn't need to be centered. OK. And PeopleList needs-- void callback, or-- is it void callback? FITZ: Yeah, I think so. FILIP: Basically a function that says-- uh, no, it can't be a void callback. So it's a function that takes a person and is called personTapCallBack. FITZ: And the-- what is your-- what is your goal this callback? What is this one? FILIP: So-- so this is-- wait. FITZ: In the-- the left-- um. FILIP: Yeah, this is basically what I want to add here to onTap. Ah, I don't know if you see it. FITZ: Yeah, OK. Yep. I see your selection. This code together thing is interesting. So it would be-- um, this callback is used to tie the two-- the detail and the list together to make sure we have both of the same things selected on both. FILIP: Yes. So-- so that NarrowLayout and WideLayout can do their own thing because it's going to be different. We can't hardcode the Navigator.of because then the way layout would look weird. but you would select something and it would create a new screen. I mean, unless you're thinking of somehow overriding the Navigator and showing in white layout the new-- the new thing in the window next to the first one. Am I making sense? FITZ: Uh, I-- I think. I think that that's similar to what I was thinking. FILIP: It would be more elegant-- it would be more elegant to just say to the Navigator, hey, we're going to person, Fitz, and-- and it would just like replace that part of the screen or create a new page on the stack. So I don't know. FITZ: Right. I think-- I'm seeing now where you're thinking with a callback where in the narrow layout, it would do this new page route onto the Navigator. And in the wide layout you don't really need the callback, it just kind of upates-- FILIP: You do, because the wide layout needs to update the other part of the screen, right? If I tap like, Clemons, then it should show on the right-hand side. FITZ: Right. Yeah. This is-- this is-- can be sometimes where state management comes in because then it would be nice if that-- on the wide layout, that widget isn't replaced. The state just gets updated. FILIP: Yes, yes. Let's do the hacky thing first, then we'll-- FITZ: OK, yeah. FILIP: OK. FITZ: Always fine with the hacky thing. Let's do it. Hacky-- hack it all together. FILIP: All right, so this is final, and then PeopleList takes this callback-- I think I'll make it required named parameter, this person.TapCallback. It should be probably named onPersonTap just for consistency. All right and here-- so NarrowLayout basically just has the people list in it, which is great. FITZ: Right. FILIP: PersonList-- uh, PeopleList. And it does exactly this-- FITZ: Mm-hm. FILIP: Does it scroll for you, for example, on-- FITZ: It does. It's the sharing scrolls enough for me to keep up. FILIP: Oh, perfect. FITZ: Yeah. FILIP: All right, so this works. And then this is basically onPersonTap person. This looks pretty good to me. And it still works. I'm just clicking around to see that everything works on the NarrowLayout. And now let's do the WideLayout. So WideLayout will now be row, right? It's a row. FITZ: Right. And it'll have the people list on one side and initially nothing slash an empty person detail. FILIP: Yes. So it will be a flexible-- let's-- well, let's not think about it yet. So it's-- it has the first one on the left is the PeopleList. And we will not do anything first with the person when it's tapped. And the other thing on it would be just a container or a placeholder. FITZ: Right. FILIP: All right, so-- oops. And we get an error. Um, null check operator-- OK, what's going on here? Of course, Render Viewbox-- oh, yeah so the classic vertical viewport has given-- was given unbounded width. So what would we do with this is we are going to say that this will be-- I think this will be expanded with a flex of three, and this will be expanded with the flex of two. And it works. So we now have-- we can't do anything in the list, but now it renders correctly. Fitz can't see it, but hey can imagine how great it looks. FITZ: And this, in my mind, is kind of getting a little bit into the difference between adaptive design and responsive design, right, where we started with the adaptive design and we said, OK, we are going to make our app such that it can adapt to different sizes, whether our window is this big, whether our window is this big, however big it needs to be. But then, within that, it depends on our content and it depends on what our content does. And we don't really care how much it takes up, we just want it to be, like, this thing is 2/3 of the screen and this thing is 3/3 of the screen or whatever it needs to be, whatever the ratios are. And that's really the more responsive part of it, saying we're going to change things around. We're going to be flexible. We're going to expand into the space that we require based on some settings, and that's what the flex factors are doing here. And that's, to me, really the difference between responsive and adaptive. FILIP: Yes. I agree. Let's finish the one we've got because I think we're very close. And then I think for now, I'm pretty happy with this. So we can take it for another spin in the next episode, maybe, of "The Boring Show" and make sure that this actually works and looks well on desktop or what have you. FITZ: Mm-hm. FILIP: But for now, also we could look at the Navigator because I really like the idea of, like, having it-- you know, like-- especially with the new Navigator-- FITZ: Oo. FILIP: --where you can deep link into the state of the app where we have selected Fitz as a person and we see his detail there. All right, but first things first. Let's just make sure that this actually works. So if the person in WideLayout-- OK, so it needs to be a stateful widget now, WideLayout, right? Because, I mean, some state needs to be set so that WideLayout knows what to show. FITZ: Yeah, so we know which person is selected and therefore, we can tell the PeopleList where to go, where to scroll to. And then the person detail-- which one to show. FILIP: Yes. So this is already very, very nice because if a person is-- if the person is null, then-- was null-- then it's Placeholder. And if it's not null, then it's a PersonDetail, right? FITZ: I think you have an extra underscore-- you have a misplaced underscore in two places. FILIP: Wow, that's more than usual. Where did I-- FITZ: Line 57. Your have your type defined as person_. FILIP: Yes. Well, I want this to be-- it's not the type. It's-- or maybe you see a different version than I. But I have Person _person like my person wants to be private to-- FITZ: I might be seeing something different because I see person_ space _person. FILIP: Oh, OK. Yeah. That's CodeTogether acting up. FITZ: OK. I'll trust that your view is showing the right thing, then. FILIP: Yes. All right. So-- so that's one thing, but we're not setting it. The way we will set it is so simple now. It's just setState and _person is now person that was clicked, right? FITZ: Yup. FILIP: And now we have an error. FITZ: Oh, cool. FILIP: Oh, no. This is because I am-- OK, so this is-- it trips me out every time, but unfortunately, there is nothing much that we can do about it. If you hot rule out something and you change your widget from stateless to stateful, a crash or it will just not hot reload. So if you see something like this, type is not a subtype of status widget and you just changed something from stateless to stateful. This is why you have to, unfortunately, hard restart. But now-- all right. And we have a full-blown contacts app. And I'm going to make a lot of money by putting it on the app server. So-- so this is great, and it-- I'm just, like, changing this. I mean, I'm rotating the screen and it still is adaptive. And I see one problem with this is that we are losing the state as we move to the NarrowView and then back to the WideView. We are losing the state of the selected person, which is-- FITZ: So we're probably rebuilding-- rebuilding all the widgets, and then the state gets dropped-- FILIP: Yes, yes. FITZ: --because we're rebuilding something higher up than our state-- full widget. FILIP: Correct. And so which is the WideLayout state. And this is to be expected and this is something that we would either fix by having the Navigator do the right thing or having an actual state management approach, where we are not just using said state but we are actually changing the-- kind of the state of the app right? But, yeah. This is how we do adaptive layout. I think we-- again, we want to touch on, like, using flags in the next episode and stuff like that. Because it's very-- it's not just if-else statements. Flutter gives you a lot of option of how to make things. How do you call it-- is it not adaptive design? Is it flexible design? What do you call it when you're using flex? FITZ: I think that's responsive, yeah. FILIP: Yeah, OK. OK. Makes sense. FITZ: Yeah. And I think that's also a good point to emphasize is, we really only have one if statement in here. And that's to define our breakpoints on whether we're doing the wide versus the narrow and that's it. There's no other statements we don't have to worry about really any other configurations there everything else is-- Hopefully. when we get to more flexible designs, a little bit responsive. FILIP: Yes. I have nothing more to add do you have something, Fitz? FITZ: Um, I don't think right now. I think for the next episode, we can dive more into other things because everything else I can think of is. like, kind of involved, so maybe we'll leave that for the next one. FILIP: Great. Well, thank you for watching, and I hope that this-- yeah, this answers some of your questions and see you next time. All right. FITZ: Thanks Phillip, we'll see you next time.
Info
Channel: Flutter
Views: 50,582
Rating: undefined out of 5
Keywords: GDS: Yes, adaptive design, adaptive layout, how to create an adaptive design, adaptive design flutter, adaptive app design tutorial, responsive app design, adaptive app design, Flutter, Flutter 101, build your app with Flutter, google, github, build an app, learn to code, how to make an app, app building 101, Google developers, Google, new in tech, tech, codelab, Flutter codelab, the boring flutter development show, the boring show
Id: n6Awpg1MO6M
Channel Id: undefined
Length: 45min 43sec (2743 seconds)
Published: Fri Feb 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.