The Boring Flutter Development Show [Pilot Episode]

[BEEP] [MUSIC PLAYING] ANDREW: Hey, everybody I’m Andrew from the Flutter Developer Relations team With me is Filip And today we’re going to do some live coding And Filip– FILIP: Yeah, we’d like to just live code a whole app, maybe in parts We’re basically going to probably do a lot of bugs, be stumped on things And I think that that should be part of the experience of the video so that you can see how we hopefully get out of these [? big holes. ?] ANDREW: Yeah, much like the people out there, we are very busy and under-prepared FILIP: Exactly ANDREW: Yeah, all right So Android Studio, we got that open? FILIP: Yeah, well, do you want to talk about what the app should look like and how it should be architected? ANDREW: Sure, yeah, that’s a good idea We got a whiteboard FILIP: If you’re not familiar with [? HackerOne ?] use, it’s basically– what do you call it? It’s a [? noose ?] app People submit links And these links are presented as a list And that list is stack ranked according to some algorithm And so what we’re doing today is very simple We have a list of these articles somewhere And we just want to make a pretty nice looking thing, an app for Flutter that has the listings The listing can be expanded if you click on it And it’ll show you the link, which will open a browser window And it will show you some stats maybe about the thing, so pretty easy hopefully no big surprises ANDREW: And a bunch of people make apps like this, right? It’s kind of like, it’s similar to To-Do on PC FILIP: Exactly, this is the new To-Do on PC, basically, what I hear So yeah, so let’s get coding Going to start a new Flutter project, and it’s going to be an application And it’s going to be called hn_app, let’s say So Flutter is going and getting the initial packages ANDREW: So this is Android Studio You have the Flutter plugin installed already, right? FILIP: Correct, yes ANDREW: And that’s just from the regular old Android Studio preferences? FILIP: Yes ANDREW: You go in and look for Flutter, and there it is FILIP: Correct, OK, so what we’re going to work with is probably iOS simulator just because– I don’t know And so what we have when we create a new app in Android Studio, a new Flutter app, we get this application that most of you have probably seen hundreds of times So let’s run it This will do all the magic that [? EXCO ?] does normally when launching an application But then we’ll be able to have [INAUDIBLE] and everything ANDREW: So you’re loading– you just– you’re building an iOS app in Android Studio FILIP: That’s right ANDREW: OK, just checking FILIP: You should be used to this, by the way, but OK ANDREW: There it goes FILIP: So this is the good old counter-app So what I’ll do first is that I’ll just get rid of everything that we don’t need We don’t need this We don’t need this We don’t need the counter We don’t need this, this, this, this As you can see, it’s very well documented We don’t– ANDREW: Yeah, not bad for out of the box app state FILIP: And we don’t need a floating action button So we’re fine ANDREW: We’re not posting anything, right? FILIP: So let’s do reload What do we get? OK, hello ANDREW: So what just happened when you did that? We should probably talk about that FILIP: We should? ANDREW: Yeah, because you didn’t fully recode that app It only took like a second to do what you just did, right? FILIP: That’s right, yes I did a full restart It’s not that hard to reload because I knew that I deleted things, state things But otherwise, yeah, basically when it’s launched in your simulator, you get to do a bunch of stuff with your app And the dot VM that’s running in the simulator now will just get the new things and will update the app

on the fly So that’s really nice because both– I think we’ll see that as we go along All right, so we cheated a little bit because we prepared a list of articles as if we already took it from the JSON API that [? HackerOne ?] use provides Just so– we will probably use some of the future videos to maybe show how you would do this But let’s assume that we already did the work, and we have the list of articles, and it’s loaded So I have it over here So we’ll create a [INAUDIBLE] ANDREW: OK, so we have a data class, a data object And we got some mocked up data that we can use FILIP: That’s correct, yes ANDREW: To get the UI going, perfect FILIP: So Dart File We’ll call this Article And so as you can see, this is a very simple class that just has some– not methods– fields And it has a cost constructor because we’re– this is an immutable object And then we have, what I just cut basically, copied-pasted with some RegEx magic from actual [? HackerOne ?] use So this is very current at this time ANDREW: Yeah, everybody is going to know when we filmed this They’ll go back and search for these headlines FILIP: And we have that So we can import it and try to show it ANDREW: Cool FILIP: So OK, import Article Let’s try this The easiest way is just we have a list of Article And it’s Articles This is ugly, but– ANDREW: That’s OK It’s a mock So the other file’s exporting the Articles list as articles, which is just a global– a variable hanging out in the globalized phase FILIP: OK, we could– well, let’s wait until [? together. ?] We can make things more real and a little bit harder on ourselves But let’s start with this I think it’s a good way So this is a column with children We could intentionally break the app, I think, now if we just did this ANDREW: Why not? FILIP: So I’m just going to– instead of doing a column of widgets, I’m going to do articles and map And each article will become its own widget So article becomes new Text, let’s say ANDREW: Yeah, just do a text with the article title or something like that FILIP: Article, they call it text, right Oh, and it’s a list ANDREW: There we go FILIP: OK, so if we start now, OK So it actually works I hope it didn’t break It should be– so maybe if we had more articles, I don’t know You definitely cannot scroll with this ANDREW: That’s a good point Do you want to take a second? Let’s talk about the structure of what we got here FILIP: Yeah ANDREW: OK, so we have we have a build method What class are we in right now? So it’s– FILIP: This is the– OK, so this is the app OK, so this is main We start with main We just call this Flutter function that just calls, just runs your main widget as an app So your app, everything in Flutter is a widget Your app is a widget So you have to say, this is the main widget So run app My app doesn’t really have much except for Building And then we have a Home Page We wouldn’t– in theory, we don’t even have to have two widgets here We could just have the home page But in later episodes we’ll have more than just on the home page We’ll have detail pages and stuff like this So it’s a good way to start And then we have the state of the home page And that has a build method And that build method can, yes, according to the current state, can draw the widget ANDREW: OK, so let me see if I followed this We have a main method that calls runApp on this app class that you made And there was something called a material app in there

FILIP: Right ANDREW: What is that doing? FILIP: Yes, that’s again another widget We can actually– this is nice because everything is in [? data. ?] So you can go very much– ANDREW: So we have source for this FILIP: Yes ANDREW: That’s cool, OK FILIP: So this– so as you can see, my little app is a widget that brings a lot of things together It’s basically like– a convenience widget Because if you went to this and looked at the build method well, you’d see that it’s just basically a lot of widgets inside each other One thing about being a framework full of widgets is what I think some people call “extreme composition over inheritance.” So it’s like, if you want to add behavior to anything, you just wrap it in a widget You don’t like add– you don’t inherit anything from anything else So you get all these like pretty deep [INAUDIBLE] trees of widgets And together they create an app So yeah, this is Material app That Material app has some cool things, like it’s very easy to do at home It’s easy to add things like initial route ANDREW: Wow, that’s a lot of stuff FILIP: Yes, but we’re not going to use it ANDREW: (LAUGHING) I’m glad FILIP: And then you go with a home page And home page is– it doesn’t– it’s not a material thing It’s just a page And in that page, there is a scaffold, which is a material thing Scaffold is basically what you see here And again scaffold has a lot of nice things like it can have app bar, which in our case is just text ANDREW: So that’s where the title comes from at the top FILIP: That’s right, yes Then we have the body obviously But you can also have floating action buttons You can have footer buttons, drawers from left and right– or I should say from start and end ANDREW: Start and end depending on which language FILIP: Yes, and many other things, so yeah, so these are all widgets And what we’re working on now is basically just this So we have this body And in this body, we have a center, which we don’t need actually Let’s get rid of it ANDREW: And it still looks the same, OK FILIP: Yeah because we are centering a column that goes all the way from left to right So it doesn’t do anything really We would have to do this– we would have to center this widget for this to be maybe– nope See? I don’t know ANDREW: This is fun [LAUGHING] FILIP: Maybe this one is why, oh, yeah, OK ANDREW: So the good news is that because this thing reloads so quickly, we can just mess around and figure out what works and just keep saving our changes and causing it to reload and see what happens FILIP: Yes ANDREW: OK FILIP: So I think what we want to do now is to start working on these items, right? So right now we are just creating a text widget for them, which is not very exciting So basically all this episode we’ll just spend on this few lines, on this one line right now Let me create a build item Create a method And so build item will create a widget ANDREW: Wow, it just– so it knew the signature for the method based on what you were using with math there That is pretty slick FILIP: Yes, I like that So we can just do this How are we doing it? This now, and now [INAUDIBLE] Oh, is this still– [INTERPOSING VOICES] ANDREW: Green of death FILIP: Yeah, OK, so this is cool This is cool I actually wanted to do this because see? We were in an error state And I recovered from this And I’ll just run [? safe. ?] And it’ll hot reload And if we were in any kind of state, as in like we had something in our cart or we were in a sub– screen somewhere, it would just recover it there, which I think is pretty cool Because you can screw up

It will throw all these errors at you But it will still keep the state And if you hot reload, you get back to it So for example, if the text starts with– let’s say, data, return null ANDREW: So you just intentionally– FILIP: Yeah, I’m trying to intentionally break just one of these And it doesn’t let me Yeah, it knows that I cannot [INAUDIBLE] here How do we break it so that it’s– ANDREW: Would you need separate build methods up here? Since you’re doing one build, it can only break once Then it breaks the whole way, or– so are you saying that under some circumstances, you’ll have like one widget broken? And the rest of the UI will look OK? FILIP: Yeah, that’s definitely something that happens But I don’t know how to do it now ANDREW: I’m sure we’ll have plenty of chances, I assume, to screw this up in all sorts of wonderful ways FILIP: All right, so back to back to business I’m just– article– so how do we make this prettier? This is nice, maybe not so nice ANDREW: The data is technically on the screen FILIP: Yeah, I kind of hoped– at the start, I hoped that just having column here is a bad idea And it is a bad idea because you cannot scroll You cannot do anything Actually maybe I can make it break a little bit I’m sorry I’m just [? in love with ?] breaking thing So let’s do style And font size is going to be something big Ah, thank you ANDREW: Yeah, what is that? FILIP: All right, so we made the text so big that we are actually getting over the allocated space of our body And that’s because we have a Column And Column doesn’t support being scrollable or anything like that So Flutter helpfully– this is a [? T-bot build ?] So helpfully Flutter says, hey You’re trying to render something that smaller– on a surface that is smaller So I’m going to give you these things that basically tell you, hey You’re overreaching in this direction You probably want something else in Column ANDREW: Then did something pop up in the console as well? FILIP: Sorry for the small text But basically this is explaining what happened ANDREW: That’s a long error message, nice FILIP: Which I love Let’s fix this by maybe using a widget that does scroll, something that– ANDREW: There’s a widget for everything including scrolling FILIP: Yes, OK, how about we use a widget that is a list view? ANDREW: OK FILIP: Because we have a list And we have a– we want to view it And there we go We have a list view ANDREW: That was quick FILIP: What other things do we– as you can see, you can do [INAUDIBLE],, this can be– the access can be horizontal So we can actually scroll to the left and right And the physics can be custom and stuff like this But let’s not do this Let’s actually work with the items themselves So what do you– Andrew, what do you not like about this list? ANDREW: Well, I have no idea where one thing starts and another thing ends That would be one thing FILIP: So we might want to do padding maybe? ANDREW: Yeah, just a little, I mean, that would certainly set them apart, right? FILIP: Oh look, padding ANDREW: Oh, that’s cool How did you get that to come up? FILIP: Alt-Enter So we have some padding We could do more Let me– ANDREW: So padding is a widget too FILIP: That’s right ANDREW: Interesting FILIP: Is this better? I don’t know ANDREW: Yeah, they’re like distinct things FILIP: We also probably want to show more than just

actual name, right? So for that we have another widget And that is called ListTile I think that’s the name And it has Title So this wasn’t that big of a difference But the thing is that ListTile has other cool things like– oh, let me [? reload ?] this Like subtitles, which would be maybe the number of comments ANDREW: Yeah, I guess we could start with that, sure FILIP: So Article comments count comments Oh, and this is– so Title wants a text The cool thing is that so at first it’s infuriating You’re like, I just want to add text to the subtitle But then you realize, wait So if Subtitle wants a widget, which it does want a widget, then I can actually add anything to the subtitle So your subtitle can be a meme Or your subtitle can be a new, small app with small scaffold ANDREW: So you can just give it a widget, whatever you want? FILIP: Yes, so let’s start with something like that OK, that works Do you see it? ANDREW: Yeah, it’s pretty cool What about if I tap on one of these? Say I want to actually pull one of these up It’s cool to look at the tiles and stuff like that But what if I wanted to actually exit? How would we do that? FILIP: So we have onTap here– onTap onTap is just– ANDREW: Is that just a property of the ListTile? FILIP: Yes, so anything can be clickable if you again wrap it in a widget that is– I don’t know how it’s called But I know the material way is to use what they call Inkwell So Inkwell is another widget And Inkwell is cool because it not only gives you onTap but it also automatically creates the cool material– ANDREW: Oh, the splashy thing FILIP: –effect, yeah, the splashy the thing ANDREW: OK, I’m sure that’s the technical term for it FILIP: Oh, yeah, splashy thing ANDREW: The splashy thing FILIP: So we’re not going to do– well, I mean, ListTile takes care of all that So even if I don’t do anything here, now we can tap things And it’ll do the right thing But we can actually do things So we want to launch a URL, right? And so this is– because we are building an app that will work on both iOS and Android, we want to use something that will work in both And for that reason at least I know about a library– within FireWorld we call Plugins– that will work for you in that respect So basically we’re going to import a plugin from our package repository, which we’ll show you And then we’ll come back to this and just use that plugin to open things in whatever browser you have installed on whatever platform that you are running this on So that package is called URL Launcher ANDREW: So what did you just open? That’s a new file, right? FILIP: Yes, pubspec, do you want to talk about this? [LAUGHTER] No, I can ANDREW: I’m happy to be the person asking questions FILIP: Yeah, I know OK, so this is pubspec.yaml This is the file where you basically configure a lot of things around your app This is the same file that Dart uses Flutter uses it So there are things that are in every pop spec And probably the most important is the dependencies I would just– basically you just say, if you know what you’re doing– let’s say we don’t know what we’re doing And let’s say– ANDREW: A reasonable assumption FILIP: Yes, so if you don’t know what you’re doing, you go to Flutter packages And you land here And you’re like, OK I want to watch URLs And first of all, you’ll see– ANDREW: So do a lot of other people, it turns out

FILIP: But let’s just open it So this is basically all you need to know about that particular package It has changelog example It has installing And basically what installing of every package on pub tells you, it’s just, go to a pubspec.yaml file Go to dependencies at this one So that’s what we’re going to do ANDREW: So just put this– this would be like updating your Gradle file in an Android app or dropping it on a CocoaPod, something like that FILIP: Yep, you can just do a Packages Get That’s going to install it hopefully– ANDREW: You lied to us, Flutter Packages FILIP: You know what? I don’t have time for this It might be that 3.0 depends on the latest version of Flutter, which I don’t have installed because I’m on a beta because I don’t want everything to come up in flames ANDREW: You’re on a stable beta version, not the bleeding edge OK, that makes sense FILIP: So we now have URL Launcher Let’s look at the example here url_launcher OK, so it has two methods basically– not methods but functions One is canLaunch, which basically checks if you’re ready for this, if on the platform that you’re using you can launch this kind of URL Remember, URL can be more things than just http or https So let’s do that So we go back to Main And we are– ANDREW: We got to probably import it right? FILIP: Import package OK, and we do– oh, wait We don’t have the URL in this mock We have mock data And we only have the domain, so we’ll have to go around this, but anyway ANDREW: Do you want to just add a dummy URL to each one real quick? [INTERPOSING VOICES] FILIP: We do have the domain, so we do we can do HTTP and the domain Let’s just– yeah ANDREW: Sure FILIP: And this is the article domain That’s very helpful So now canLaunch, if you go to the info about this– wait, no I want canLaunch Anyway, so canLaunch will give you back a future of [? bool. ?] If Can Launch– ANDREW: If is a synchronous statement You can’t deal with the future in there FILIP: So the reason why canLaunch gives you a future is because it could take some time before it knows that you can or cannot launch this URL So we need to do this asynchronously Let’s see if this works Async/await is something that [? that ?] can do And you can basically– whenever you have a future and you want to wait for it, you do await So now we’re like– this basically translates to first, do canLaunch Then wait for the [? bool ?] that comes from there And after that happens, do this logic ANDREW: And I can do all that on my onTap method? FILIP: That’s right I hope so ANDREW: We’ll find out FILIP: So we are awaiting if we can launch And if we can launch, then we launch OK, let’s do– let’s extract this to a fake URL And this is also something that brings back future This time this is because we might want to just wait until it opens or whatever ANDREW: A music player app or something like that, you might want to know that you just left or something like that FILIP: Maybe, I don’t actually know But we have that now And so we can see if that works ANDREW: So I guess when you did the update to the pubspec file,

you had to bring down a whole app FILIP: That’s right, a bit of suspense, all right So now– ANDREW: It looks just like before FILIP: It looks just like before We can still scroll And then we can click And it launches, and it launches ANDREW: There it goes FILIP: OK, and this should work in Android as well Should we try it? ANDREW: Yeah, we haven’t pulled up an Android emulator yet, right? It looks like it might– FILIP: That’s going to take a ANDREW: Yeah, starting from scratch is going to take a minute FILIP: Let’s– ANDREW: Oh, wait That was a very quick boot FILIP: How do I– I have it on so that it’s always on top And now I can’t move it for some reason So I cannot– let’s do this ANDREW: We’re very high tech here FILIP: So this will go and initialize the Grable things So before we did EXCO because we were running on this iOS simulator And now we’re trying this in the Android ANDREW: But the hot reload stuff, all that works the same once it’s up and running? FILIP: Yeah ANDREW: OK, and we can have two Have an emulator now and a simulator going at the same time FILIP: I’ll [? pull ?] [? my book. ?] ANDREW: I don’t know if you’re picking up the fan sound But the machine is doing its best FILIP: It’s also recording the screen ANDREW: Oh, that’s true Go, go, go, go, go There we go FILIP: And we should have all the cool things like scrolling And maybe we should call out how this is different On iOS, it does this ANDREW: So that pulls down And on Android, you get the shadow And that’s out of the box You didn’t do that FILIP: Yes, and it opens the browser, all right ANDREW: And so here you get the default browser, which is Chrome on the emulator And you can get Safari on the iOS FILIP: Correct, all right, so I think we can kill this one Thank you, Android emulator Thank you ANDREW: Please take no offense as we force quit you FILIP: All right, maybe it’s time for us to– yeah, we’re still here– show you some of the cool things about the Flutter Inspector So with Flutter plugin into IntelliJ, you get Flutter Inspector, which is something that let’s you do– A, it gives you the ability to change platform So here we’re running on iOS But because Flutter is drawing everything– it owns all the pixels– basically it can pretend that it’s on Android now So what we can do is just this And this doesn’t look like much But now you see that– ANDREW: There’s the Android shadow FILIP: Yes, if we go back, you can see that in an Android, you would have your title on the left On iOS by default you’d have it in the center of the app, and so on and so forth So that’s nice There’s also things like Performance Measurement So you will see– do you skip frames? There are other things Timeline, let’s not go into this And also these helpful things that will tell you, oh, there’s padding here This one is scrolling, and so on and so on And then you can go on and do– you can select things Normally you’d be able to select things And of course you can look at all the crazy ANDREW: So those are all the widgets FILIP: Yes, you got it ANDREW: Whoa FILIP: And then you can go to a Render [INAUDIBLE] to see in the innards of Flutter, how this is all rendered But again I think we’ll go into this in another episode maybe sometime in the future ANDREW: Clearly a lot there FILIP: Yeah, all right, so I’m not happy because I don’t know if you know this But whenever I clicked anywhere, it just launched So what I think we need to do now is whenever you click on one of these things, one of these item,

we want to expand that item and then show you a way to open the comments ANDREW: Want to whiteboard it on here? FILIP: Oh, yeah Thank you ANDREW: Go for it FILIP: So you click on this one Oh, it doesn’t– thank you, Andrew ANDREW: I’m a very helpful– go for it FILIP: So it’s not really like that, but if you click it, it gets longer And it has some text And maybe there’s a button or two for you to click And then if you click it again, it’ll unexpand back ANDREW: So how are we going to do that? FILIP: Yeah, I think there is a widget that lets you do exactly that Also, we didn’t talk about List Builder and things like that I wonder– ANDREW: Yeah, you’re just dumping a bunch of children in this list, right? FILIP: That’s right Yeah, so in a real world, and again maybe that’s just another episode But you’d want to have infinite scrolling lists, which will just load new things as you go along This is obviously possible Basically you use the same thing here, but it’s called ListView Builder And then you will provide some other things But now just to keep it simple, we just have ListView that has a finite amount of children, a list of children But what I wanted to do is the expandable file Let’s see, expandable– Expansion Dial And so it gives us different things So we are going to do children Let’s just do– ANDREW: Want to just throw some text widgets in there and just see what pops up where FILIP: And we might want to need this later Is this– yeah Oh, it gives us a little bit like this ANDREW: And so you get a little icon OK, so title is the part that’s on the top And children is the expansion part FILIP: And we can obviously make this– ANDREW: Can you expand more than one at a time? You can Is it changing the text color when you do that? FILIP: Yes, it is So I wonder, do we need this? Do we want this? I think it’s pretty cool So let’s stay with this So this doesn’t look good So let’s do a row We need a row We need a thing that tells us the number of commands and then maybe gives us a button that will launch the browser So I wonder if that is already doing a row because we’re giving it children, not child So let me just try it ANDREW: Just give it two texts, see where they come up FILIP: Oh, it gives us a– oh, that makes sense ANDREW: So it’s a column then, right? FILIP: Right, it’s a column It doesn’t– nothing prevents us– again everything is a widget So nothing prevents us to do rep [? with row, ?] right? ANDREW: I gotta remember that all Alt-Enter thing that you’re doing That’s pretty slick FILIP: Yeah, this is pretty fun And then so we can have a new button Can we have a button, flat button? ANDREW: I think there are kinds of buttons FILIP: Oh, material button, oh, wow, now I can’t– ANDREW: There’s a lot of buttons FILIP: Dropdown [INAUDIBLE] [SIGHING] Choices, choices, material button, OK, let’s not do anything yet ANDREW: So how do we put text in the button? FILIP: Child, so most widgets do have a child or children ANDREW: So yet again, you’re just going to jam a text widget into it FILIP: Yes, open All right, and that’s– ANDREW: Can we give it a color? FILIP: Oh, sure, like background color? ANDREW: Yeah, there was a theme object up at the top, right? FILIP: That’s right So we can give it– what color do we want?

Colors– red ANDREW: Sure FILIP: Oh, yeah ANDREW: Every article gets a big, angry button How about green? Green’s a good color Is there a green? There you go FILIP: All right, OK, so clearly we’re not designers ANDREW: Next episode FILIP: All right, so this works And also I don’t love that it’s kind of squeezed here ANDREW: Yeah, we don’t have as much padding FILIP: Well, we can add padding But we can also, I think we can– MainAxisAlignment And let’s see what’s– yeah, spaceAround maybe ANDREW: Whoa FILIP: Is that better? Oh, spaceBetween ANDREW: So what is MainAxisAlignment? That seems important here FILIP: Yeah, so that’s basically– that gives you– in this case, the row gets the full width from this part to this part ANDREW: So it expands to fill whatever contains it FILIP: Right, so by default you have MainAxisAlignment.start, which just, in that space you just start on the left or on the top or whatever This is why it’s– because MainAxisAlignment for a row is horizontal For a column it’s vertical ANDREW: So whichever way you’re expanding as you add items, that’s your main axis FILIP: Yes, and then you have cross axis, which is what’s crossed to that ANDREW: Perpendicular to that, OK FILIP: So this is useful because I could change this into a column, and it would still, I mean, it would look different But it would still take the same thing And it would still– ANDREW: So now they’re jammed up at the top instead of jammed up at the left, OK That makes sense FILIP: So I think what we want is either space between our space around I think this looks good Does it look good? ANDREW: What about just having an icon instead of the word “open?” Can we do that? FILIP: Sure ANDREW: Is there an icon for “get out of here” or something? FILIP: Icon button, which takes– ANDREW: Probably has an icon property that’s not getting set FILIP: Yeah, so icon is– let’s say, Launch ANDREW: Oh, there you go FILIP: New icon, sorry I always forget, Icons.launch Again Icon can be anything And so we don’t need this This looks– ANDREW: Yeah, that’s pretty cool FILIP: This looks pretty good I don’t think we need green We’re not designers [LAUGHTER] So anyway so we have that I think that’s pretty cool Oh, it doesn’t do anything ANDREW: Oh, that’s right We got, we have a blank onPressed FILIP: So let’s do this Oh, yeah ANDREW: Yeah, that’s crazy FILIP: OK, so that works Oh, the last thing that we wanted to do today, I think, was to enable you to reload So obviously if you read [? HackerOne ?] use, you are reloading like five times per minute So we want to make it easy And the usual way to do this on a mobile device is to– how do you call it? ANDREW: Swipe down to pull to refresh FILIP: And now I’ll need your help because I don’t remember what it’s called ANDREW: OK FILIP: We can just– ANDREW: Fortunately we have this research machine over here FILIP: That’s right And it is connected to the internet, this one as well So let me try I found it So if Flutter has this Flutter Gallery app, which tries to do a lot of things and shows you how to do them So this is available and iOS, I think, and Android as well as a downloadable app that’s just there But it’s also– the whole app is open source So you can look at how they do things And how they do things is they use– for example for the overscroll is here ANDREW: Oh, it appears to be a class FILIP: Yeah ANDREW: A widget that supports the material

“swipe to refresh” idiom FILIP: Sounds like what we need So we probably want to put it here around the List View ANDREW: Makes sense FILIP: So Wrap RefreshIndicator ANDREW: And there it is FILIP: And it needs what? ANDREW: Child FILIP: What is it? It’s screaming about– onRefresh is required OK, so we do– ANDREW: So this thing handles all the graphics, all that scrolling And you just tell it what to do when somebody pulls it to refresh FILIP: Right ANDREW: That’s pretty slick You just reassigned the list to our mock data FILIP: Yeah You know what? ANDREW: Can you do like a toast like on Android or something like that? FILIP: Yes, that’s what I’m going to do ANDREW: There’s now– oh, there’s snack bars now That’s right Toast is– Snack Bar is the new hotness FILIP: Context will be– ANDREW: Are you going to give it a text widget? Because that’s just what we do with everything Everything gets a text widget FILIP: Refresh Maybe we need to somehow tell it to not do this Also it’s async Let me– so a function that’s called when the user has direct the refresh indicator far enough to demonstrate that they want the app to refresh The return future must complete when the refresh operation is finished ANDREW: Return future, you say FILIP: OK, so return What does it need to finish? ANDREW: I’m just going to look up an example FILIP: Oh, no, OK ANDREW: Name of thing, word example, let’s see what comes up FILIP: Oh, we got– ANDREW: So I think it wants you to return a future And since we’re using mock data, we can’t just steal one from the return value of some http call, right? Or you could You could just– you want to just make a call to Google.org real quick? FILIP: No, if you want– so we could just do return new Future, delayed, and have a duration of maybe a second And what it’s going to do is basically exactly what we want ANDREW: And there it was So you made just a dummy future that completes after a second FILIP: Yes, and it needs– it doesn’t want any value there So it’s a future of null This one– ANDREW: Yeah, it just needs to know when you’re done FILIP: Yeah, so what we can do is we can async And then we can do like, Await that future first, just to be like, look like we’re doing something, and then we can remove ANDREW: Want to just pull the first one? That way you could see it See at the top? FILIP: Hey ANDREW: Isn’t it like a removeAt? FILIP: Yeah, removeAt And since date, this is the first time that we use it today Right ANDREW: So we’re no longer we’re turning a future, though Is that OK? FILIP: Because we’re in async, we are actually ANDREW: By default FILIP: Well, yeah, when you’re in async and you await at any time, actually by default you’ll just return a future of whatever So in this case, we don’t even need this here, I think Because you have a return of that So let’s do this, oh, yeah ANDREW: There it went Madly delete things all the way down

FILIP: Yeah, this will break when we get to development But let’s not do that maybe All right, so– ANDREW: So let’s cover what we just did So we made a brand new app in Android studio You ripped out most of the code that starts in a default app We added a data class for the articles We added just some mock data in a list Then you dumped it into a list view that was displaying the titles at first And then we added the comments as a subheading And then we ditched that after– or no Then we made it so if you tap on the titles, you would leave Then we switched to expansion tile, which gave us that nice little pop when you click on one Added the button, moved the comment text, and added the pull to refresh I think the only thing we haven’t covered is the set state call you just added So what is that doing? FILIP: Yeah, so that just makes sure that Flutter knows that something changed If we don’t have that, then it’s not going to break anything But it’s going to be weird because Flutter will not know that the list of the articles has changed since then So it will just not refresh ANDREW: So you can change the state but you, Flutter wouldn’t know you did it because it’s just sitting in memory Who’s watching it, right? FILIP: Yeah, so nothing changes even though that first article is no longer there ANDREW: It’s still getting displayed FILIP: Yeah, but the cool thing is again, [? stateful ?] hot reload, so we put this back And now when I do this, we will see how it removes all these, like all three things Because I just did the thing, but it just didn’t show So it just went through ANDREW: So it should go down to– FILIP: Yeah ANDREW: Wow FILIP: Anyway so don’t forget your set state And as you can see, you can go pretty far without even using one But once you have state that you’re changing, you might want to have set state there We can cover again how to deal with more harder things ANDREW: I’m sure we’ll have more sophisticated use cases for this in the next episodes FILIP: That’s right So yeah, I think, I mean, so we have sets there We have talked about all this I think we’re done ANDREW: Cool FILIP: Yeah, so thank you for watching, I guess ANDREW: Yeah, all right, so next time, what do you think we’re going to do? We’ve got to pull live data at some point What else can we do? We can tighten up the [? EY. ?] I wonder if we could drag a designer into this and have someone to help us with that FILIP: Yeah, well, I think the next episode should start with actually data from JSON But then we should really have a hard look at this one, the UI, and make sure that we actually want this expansion thing because– ANDREW: It’s taking up a lot of space FILIP: Yeah, I imagine that there wouldn’t be this thing So I think we can just have something else And also what gets displayed here? We have more data that we can show here And then I don’t think we could– if we have enough time, we can show another screen And that means navigation ANDREW: Oh yeah, because most of these things have comments FILIP: –just one Oh, yeah, show the comments, exactly Otherwise I think like for Hyperion use, it’s OK to just open this in a browser I don’t think we need to parse the article or anything like that ANDREW: No, send the traffic back to good old [? YC. ?] FILIP: All right ANDREW: Well, cool, thanks for watching, everybody We’ll be back with future episodes FILIP: Thank you Bye [JAZZ MUSIC PLAYING]