Modernization Hub

Modernization and Improvement
The Boring Flutter Development Show [Pilot Episode]

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 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]

100 comments on “The Boring Flutter Development Show [Pilot Episode]

  1. Hell yeah, though I hope this becomes more about news and tips and Q/A than straight examples

  2. I really enjoyed the show. I can't wait for loading remote JSON and using List view builder. I'll definitely watch episode 2.

  3. My first ever mobile app ever created was with flutter. Flutter team has nice documentation and i wish to know create my own widgets.

  4. Hey, if you really are the google developers, I hope you see this because I need help syncing my gmail, it won't sync no matter how many methods I try.

  5. Cool video. Could you post future videos on a different Youtube channel so we can easily subscribe and watch them

  6. I would love to see how we can customize given widgets. For example remove that up/down arrow on the right or to draw brand new widgets with custom shape and behavior.

    Also I would like to see how we can call native Android/iOS APIs.

    And a bit more about asynchronous callbacks and best practices, for example I need to do some background work and notify all UI elements about the results (fail with message or OK). And what about multithreading?


  7. Thank you, Andrew & Filip, Its really a useful video for beginners like in flutter. Waiting to watch video from both you
    1. On CRUD SQLite operations.
    2. Making API requests.
    3. Customising the UI (tweaks on iOS&Android)
    4. Navigations drawer, Switching between screens etc

  8. Make more Videos like this …its Amazing …..but go and watch Fluttery Channel he Awesome in this ……

  9. Kudos to Andrew for reeling in the demo to take a timeout to get Filip to explain the concepts of Flutter.

  10. Thanks for the example. Could you please also show a more complex sample with state persistence (SQLite), service managers that are not represented on the UI layer and working with device hardware like IMU sensors, camera, file system etc..

  11. Nice Video. Anybody come up with a solution that shows the SnackBar?

    Update: I found this

  12. Humm, body property's arguments should've been wrapped in a builder, you wouldn't have got the error for the Snackbar 😀

  13. Thanks for the video! valuable information from you guys 🙂
    Just a question, which perhaps will be solved in the following tutorials:

    Just like you do at 51:40, if you open an item and then refresh the page (and thus, deleting it), the application shows the next item as open, even if it wasn't.

    Why is that? I imagined the each ExpansionTile was specific to its own item, so I expected to remove the first item leaving the others as they were. Could someone help me figure this out?


    P.S. if anyone needs the article.dart file, this is the link to the version they use in this lesson:

  14. Hi averyone…the start on flutter is weird cause dart language but you know " always learning new thinks mote"
    Ok, second stage, creating a real app with real beautiful UI … task done ! Yupiiiiiii
    Ok, so you need more features. Kind easy to implement in java/android studo…and…

    BANG! Theres is no native support to INTENTS on Flutter !!!

    Hole, s****, all the building is collapsed!!! Back to java/android studio !

  15. I put the code from this episode I will commit more after watch more 🙂 This is a very good way to learn Flutter!

  16. Love to watch this boring show about flutter from google developers. I want to excel in both flutter and AngularDart.. let me try 😉

  17. 0:56 I always wonder who writes these subtitles. Whomever, whatever it is, they clearly never heard about Hacker News which is a noose app, haha. Very cool format

  18. How would you add a working search bar to this. The issue I'm having is I can't seem to .add items in the list to a new list and then set the state to use that list if it contains a query that matches some data in the items parameters.

  19. Sir making mistakes while teaching makes this the best tutorial ever
    because i do that i make mistakes and keep editing until it works and most of the time i think i'm just a dumbass and will never be a programmer
    but after seeing a professional Goggle engineer making mistakes i'm full of confident ow and will keep learning 😀 Thank you

  20. Light mode on android studio is dead. I would forget this blasfemy because the episode was really great guys! Well done! No more light mode please x.x!

  21. I'd love to see state management best practices in the show. I am using EventBus/Vuex in Vue.js project. I'd really want to see how this relates(forgot the word here).. in a flutter project.

  22. 47:30: Snackbar.of(context) is called with the BuildContext of the entire page, which does not have Scaffold in the first place. could be used to show Snackbar based on the wrapping Scaffold

  23. Help: I get this error while Im trying to show the data on screen using list: list<dynamic> is not a subtype of list<widget>.

  24. "We'll just use the iOS simulator because…. oh shit I can't say because it's way faster than the Android emulator.. err.. just … because." Good video anyway!

Leave a Reply

Your email address will not be published. Required fields are marked *