- 00:00:15 so what is flutter
- 00:00:17 flutter is actually a package of
- 00:00:19 multiple things you could say
- 00:00:21 it's a sdk a software development kit
- 00:00:24 for creating mobile 2d
- 00:00:25 apps and that's important if you're
- 00:00:27 planning to do a 3d app
- 00:00:29 some game flutter won't be able to help
- 00:00:32 you but if you're
- 00:00:33 planning some 2d app which the majority
- 00:00:35 of apps are in the app store
- 00:00:37 then flutter is your thing now i said
- 00:00:39 flutter is a package of things
- 00:00:42 the most important part probably is the
- 00:00:44 framework it ships with
- 00:00:46 the programming language you're going to
- 00:00:48 use is actually called dart
- 00:00:49 and you don't need to know it you'll
- 00:00:51 learn it in this course but flutter is a
- 00:00:53 framework for
- 00:00:54 dart and a framework is just a set of
- 00:00:56 utility functions classes
- 00:00:58 objects you can use in that programming
- 00:01:00 language so that you don't have to write
- 00:01:02 everything from scratch
- 00:01:04 flutter ships with a huge set of
- 00:01:06 pre-built widgets for example
- 00:01:08 and widgets are simply just ui elements
- 00:01:10 like buttons sliders tabs and so on so
- 00:01:13 that you don't have to write everything
- 00:01:15 from scratch
- 00:01:15 but instead you can use all these tools
- 00:01:17 from the flutter framework
- 00:01:19 add your own code add your own logic
- 00:01:21 enhance the
- 00:01:22 code or the features you're getting from
- 00:01:24 flutter and build your
- 00:01:26 native app with these features so you
- 00:01:29 write code with one language only that's
- 00:01:31 the core thing
- 00:01:32 you don't have to learn java or swift or
- 00:01:35 anything of that
- 00:01:36 you write one language dart and you use
- 00:01:38 the flutter framework features
- 00:01:40 when writing that code you can then
- 00:01:43 find out on which platform your app runs
- 00:01:45 in cases where you need to execute
- 00:01:47 different code
- 00:01:48 this is something i will cover in the
- 00:01:49 course of course and by the end
- 00:01:51 we use that second part of the flutter
- 00:01:54 package
- 00:01:54 thus far i discussed the framework part
- 00:01:57 the set of built-in features
- 00:01:59 now flutter is not just dart code it's
- 00:02:02 also a set of tools that allow you to
- 00:02:04 test
- 00:02:05 the app you're writing on the device
- 00:02:07 with cool features like
- 00:02:09 auto reload whenever you change
- 00:02:10 something in your code and you're
- 00:02:12 running the app on an emulator it
- 00:02:14 reloads automatically
- 00:02:15 that's really convenient and it gives
- 00:02:17 you build tools
- 00:02:19 to build your code so to build your dart
- 00:02:21 code
- 00:02:22 into the native app you can upload to
- 00:02:25 the apple app store or google play store
- 00:02:27 so it compiles your dart code to the
- 00:02:29 native code
- 00:02:30 that's what it also does so flutters
- 00:02:32 both the framework
- 00:02:34 and a lot of useful tools and to make
- 00:02:36 this really clear
- 00:02:38 flutter builds up on dart dart is the
- 00:02:40 programming language
- 00:02:41 flutter then offers this framework which
- 00:02:44 is well
- 00:02:45 connected to dart or which is built up
- 00:02:47 on dart which offers a lot of utility
- 00:02:49 features and all these widgets
- 00:02:50 and then flutter has this second part
- 00:02:53 the sdk
- 00:02:54 the tools and so on you need to build
- 00:02:56 and test your application
- 00:02:58 this is flutter this is what you will
- 00:03:00 learn from scratch
- 00:03:01 you don't need to know anything about it
- 00:03:03 and we will use flutter together with
- 00:03:05 dart
- 00:03:06 to build native mobile apps and ship
- 00:03:08 them to the app stores
- 00:03:14 obviously we now want to dive in and get
- 00:03:16 started and we will
- 00:03:18 we'll install flutter and write our
- 00:03:20 first flutter app
- 00:03:21 in a few seconds but first i want to
- 00:03:23 highlight how a flutter app
- 00:03:24 looks like what its core architecture is
- 00:03:26 what its core
- 00:03:27 concepts are it's important to
- 00:03:30 understand that flutter works with
- 00:03:32 so-called widgets
- 00:03:33 and that will become clearer once we
- 00:03:35 work with them in the next module we'll
- 00:03:37 dive
- 00:03:37 deeply into them but in the end of
- 00:03:39 flutter app
- 00:03:40 an app built with flutter is just a tree
- 00:03:44 of widgets
- 00:03:45 and you can think of this as your app
- 00:03:47 being a widget a ui
- 00:03:48 element your whole app is one ui element
- 00:03:50 and then it holds other elements like a
- 00:03:52 tab
- 00:03:53 bar maybe some text fields where the
- 00:03:55 user can enter something
- 00:03:56 a button to confirm the choice and all
- 00:03:59 that may be laid out in some invisible
- 00:04:01 widgets like
- 00:04:02 columns or rows to position elements
- 00:04:04 above each other or next to each other
- 00:04:06 and then you got the visible widgets
- 00:04:08 like buttons and so on so you structure
- 00:04:10 your app like this
- 00:04:12 additionally flutter embraces platform
- 00:04:14 differences
- 00:04:15 this means that of course we use one
- 00:04:18 code base
- 00:04:18 that's the third important thing we use
- 00:04:21 one code base
- 00:04:22 to write ios and android apps but since
- 00:04:24 these platforms aren't entirely equal
- 00:04:27 flutter gives you some tools to find out
- 00:04:29 on which platform you're running
- 00:04:31 so that in cases where you need it you
- 00:04:33 can execute different code
- 00:04:35 so one code base but the possibility to
- 00:04:38 differentiate between
- 00:04:39 the platforms that gives you as a
- 00:04:41 developer a lot of power
- 00:04:43 because you have the advantage of
- 00:04:44 generally using one setup
- 00:04:46 but if you need it you can still write
- 00:04:48 different code
- 00:04:50 so that's the core flatter architecture
- 00:04:52 now let me dive into the widget thing
- 00:04:54 really quick
- 00:04:54 this is a screenshot of the finished app
- 00:04:56 we'll build in this course
- 00:04:58 and on this screen we can identify a lot
- 00:05:01 of widgets and actually there are even
- 00:05:03 more widgets than i marked here for
- 00:05:05 example that add image button at the
- 00:05:07 bottom
- 00:05:08 well that button is a widget and then it
- 00:05:10 has two child widgets
- 00:05:12 the camera icon and the add image text
- 00:05:15 and this is how you build the flutter
- 00:05:16 app and even the whole app as i
- 00:05:18 mentioned
- 00:05:18 is one widget this gives you that widget
- 00:05:21 tree where you have a root widget
- 00:05:22 wrapping the app then you have widgets
- 00:05:24 for the different pages you might have
- 00:05:25 in your app but which mean you can
- 00:05:27 navigate
- 00:05:28 obviously you'll learn this in this
- 00:05:29 course and then on each page you have
- 00:05:31 child widgets
- 00:05:32 some of them doing some layouting some
- 00:05:34 of them rendering
- 00:05:35 visual things like buttons text fields
- 00:05:37 and so on
- 00:05:38 so that is how this works the obvious
- 00:05:41 question is
- 00:05:42 how is it then compiled to native code
- 00:05:45 because we
- 00:05:46 write dart code we do that with the help
- 00:05:48 of the flutter
- 00:05:49 api the framework which gives us utility
- 00:05:52 features
- 00:05:52 built-in widgets pre-styled widgets we
- 00:05:54 add our own code build our own widgets
- 00:05:57 yes we do that a lot actually and in the
- 00:05:59 end we want to get an app which runs on
- 00:06:01 android
- 00:06:02 and ios flutter helps us with that
- 00:06:05 the dart code gets compiled to native
- 00:06:08 code
- 00:06:09 for these platforms and the flutter sdk
- 00:06:12 does that
- 00:06:12 it has tools that do this compilation
- 00:06:16 so that's really cool you don't have to
- 00:06:18 worry about that you don't have to write
- 00:06:19 any
- 00:06:20 native device code you write your dart
- 00:06:22 code using these flutter features
- 00:06:24 and the flutter sdk will do the
- 00:06:26 compilation that's pretty useful
- 00:06:28 now that is what flutter does for you
- 00:06:30 and this is how it compiles that
- 00:06:32 and with that we got a very cool setup
- 00:06:34 that allows us to write
- 00:06:36 very powerful and flexible apps and
- 00:06:38 speaking of that
- 00:06:39 it's time to create our first step it's
- 00:06:41 time to install flutter and set up the
- 00:06:43 development
- 00:06:44 environment we need for this course and
- 00:06:46 then get our first
- 00:06:48 application up and running on an
- 00:06:50 emulator
- 00:06:51 so let's do that in the next lecture
- 00:06:57 so let's install flutter then and the
- 00:07:01 installation actually differs between
- 00:07:03 mac os
- 00:07:04 and windows or the rest of the course
- 00:07:06 the code we write and so on will be the
- 00:07:08 same
- 00:07:09 but here for the installation it differs
- 00:07:11 so therefore
- 00:07:12 in this video we'll set up flutter
- 00:07:15 and all the surrounding packages and
- 00:07:18 dependencies we need
- 00:07:19 for mac and in the next video we'll do
- 00:07:22 the same for windows
- 00:07:23 so if you are a windows user you can
- 00:07:26 simply skip this video
- 00:07:27 and if you are a mac user you can skip
- 00:07:29 the next video
- 00:07:31 so let's proceed with the mac setup then
- 00:07:33 on
- 00:07:34 flutter.io you can simply click on
- 00:07:37 get started and then choose install on
- 00:07:40 mac os
- 00:07:41 by the way if you're on linux the steps
- 00:07:43 are pretty much the same but you can
- 00:07:45 also click on install on linux to see
- 00:07:47 them in detail
- 00:07:48 and that's in general what i would
- 00:07:50 recommend
- 00:07:51 go through these steps in detail the
- 00:07:54 good thing is
- 00:07:54 you can read them here and i strongly
- 00:07:57 recommend
- 00:07:58 following along here and reading these
- 00:08:00 whilst you also watch this video
- 00:08:02 or whilst you are going through the
- 00:08:04 installation process
- 00:08:05 because a some tiny steps
- 00:08:09 could change over time and b this is a
- 00:08:12 great way of resolving
- 00:08:13 issues since there might be something
- 00:08:15 you overlook in the video
- 00:08:17 which you can then simply read about in
- 00:08:19 this article
- 00:08:20 so let's continue first of all let's
- 00:08:23 check the system requirements
- 00:08:24 well we need the operating system mac os
- 00:08:27 obviously
- 00:08:27 enough free space on our disk and then
- 00:08:30 we depend on these command line tools
- 00:08:33 which actually should all be available
- 00:08:35 by default
- 00:08:36 now git might not be so it's a good idea
- 00:08:40 to download it before you get started
- 00:08:42 you can simply search for
- 00:08:44 git on google and then actually pick
- 00:08:47 that first or
- 00:08:49 actually that second link to find the
- 00:08:51 downloads page
- 00:08:52 and there simply choose mac os or linux
- 00:08:55 depending on where you're on
- 00:08:56 and then the download should start
- 00:08:59 automatically
- 00:09:00 if it doesn't you can simply click here
- 00:09:02 obviously
- 00:09:03 and this will download an installer for
- 00:09:05 which you can simply walk to install
- 00:09:07 git which is a version management system
- 00:09:10 on your machine
- 00:09:11 now you don't need to use that version
- 00:09:13 management system but flutter uses it
- 00:09:15 behind the scenes
- 00:09:16 this is why you need to have this
- 00:09:17 available once you got git installed
- 00:09:20 with the help of that installer you can
- 00:09:22 download which i showed you a second ago
- 00:09:24 you can proceed with these steps and the
- 00:09:26 next step is to actually download
- 00:09:28 flutter now at the point of time
- 00:09:30 recording this
- 00:09:31 the latest version is 0.3.2 beta
- 00:09:35 chances are that when you're watching
- 00:09:37 this there's a higher version available
- 00:09:40 but the code we write will still be the
- 00:09:42 same so
- 00:09:43 download the latest version you're
- 00:09:45 seeing here of course now i'll go with
- 00:09:46 this one
- 00:09:48 simply download it to your machine and
- 00:09:51 this can take a while as you can see
- 00:09:52 it's quite a big file
- 00:09:53 so i will jump forward to the point of
- 00:09:56 time where this already
- 00:09:57 is downloaded the installation just
- 00:10:00 finished for me
- 00:10:01 you can now simply unzip this and you
- 00:10:04 can do that with the command you see
- 00:10:05 here
- 00:10:06 or simply well click on that downloaded
- 00:10:08 file
- 00:10:09 simply open it in the folder where it
- 00:10:12 was downloaded
- 00:10:13 simply click on it down there and then
- 00:10:17 unzip this now this can take a couple of
- 00:10:19 seconds of course since it's a rather
- 00:10:20 big
- 00:10:21 file once it is unzipped
- 00:10:24 you have this flutter folder and now you
- 00:10:26 should copy this somewhere where you
- 00:10:28 want to store this
- 00:10:29 now this flatter thing here is an entire
- 00:10:32 tool set it's the
- 00:10:34 sdk the software development kit you
- 00:10:37 need for developing
- 00:10:38 flutter apps it includes a lot of
- 00:10:40 dependencies flutter needs
- 00:10:42 so this is really a central packager
- 00:10:44 program you should store in your machine
- 00:10:46 and you can copy it wherever you want on
- 00:10:48 your machine
- 00:10:50 now i got that tools folder where i want
- 00:10:52 to have it so i'll just
- 00:10:53 drag it over there and now with flutter
- 00:10:56 added to that folder
- 00:10:58 we can proceed with well the
- 00:11:00 installation or with using it
- 00:11:02 so the flatter tool is actually a tool
- 00:11:04 we execute from the command line
- 00:11:06 therefore we need to add it to our path
- 00:11:10 the path is basically a global variable
- 00:11:12 which ensures that the flatter program
- 00:11:15 or which ensures that any program can be
- 00:11:17 accessed through the command line and we
- 00:11:19 want to configure the flutter program to
- 00:11:21 be found there
- 00:11:22 now to be found there we could execute
- 00:11:24 this command
- 00:11:25 in the command line if we navigate it
- 00:11:27 into the newly created flatter folder
- 00:11:31 or we do something which is seen a
- 00:11:33 little bit further down the article
- 00:11:36 here we update our path permanently now
- 00:11:38 how does that work
- 00:11:39 for that you should go into your user
- 00:11:41 folder and there you need to turn on
- 00:11:44 the setting to see hidden files you
- 00:11:46 should then see that bash profile file
- 00:11:49 now you can simply open that with the
- 00:11:52 normal text
- 00:11:52 edit app or with any text editor of your
- 00:11:55 choice
- 00:11:56 now if you're using the text adapt just
- 00:11:58 make sure
- 00:11:59 you're viewing this in plain text mode
- 00:12:02 not in rich text mode
- 00:12:04 so if you open this then let me make
- 00:12:06 this a bit bigger
- 00:12:08 you can edit this file and this
- 00:12:10 basically configures pof settings
- 00:12:12 for your terminal for your command line
- 00:12:15 tool on mac or linux
- 00:12:17 now we want to add something here we
- 00:12:20 want to add
- 00:12:20 this line which you can find in the
- 00:12:22 installation steps
- 00:12:24 simply add it at the bottom and we need
- 00:12:27 to replace
- 00:12:28 this part here with the actual path
- 00:12:32 the folder path on to that flatter tool
- 00:12:35 on
- 00:12:35 our machine now that of course depends
- 00:12:38 on where you dragged it
- 00:12:40 for me it can be found under
- 00:12:43 users than my user name then there's a
- 00:12:47 development folder
- 00:12:48 and then there i created a tools folder
- 00:12:51 and again you really have to pick
- 00:12:53 your pop there where you dragged that
- 00:12:55 flutter tool
- 00:12:56 you can view that also by clicking on
- 00:12:59 get info here
- 00:13:00 then you can see where it's found in my
- 00:13:02 case users
- 00:13:03 my user name development tools with that
- 00:13:06 simply save that file
- 00:13:08 and thereafter open your normal terminal
- 00:13:11 app on mac or linux once you did open
- 00:13:15 that
- 00:13:15 you should be able to run flutter doctor
- 00:13:19 now this is a tool which will also check
- 00:13:21 if you need to do something to make
- 00:13:22 flutter work
- 00:13:23 and it should at least do something if
- 00:13:26 you set up your flutter installation
- 00:13:28 correctly
- 00:13:29 by the way the fact that my installation
- 00:13:31 is 30 days old we can ignore that here
- 00:13:33 because we know we just downloaded the
- 00:13:35 latest version
- 00:13:36 0.3.2 in my case so this is all fine
- 00:13:39 now this is already looking quite good
- 00:13:42 here because
- 00:13:43 i actually have a decent setup i'll
- 00:13:45 still walk you through the remaining
- 00:13:47 steps here though
- 00:13:48 so we updated our path we now ran
- 00:13:51 flutter doctor 2.
- 00:13:53 now what we need to do is we need to
- 00:13:55 configure our system
- 00:13:56 to be able to build ios and or
- 00:14:00 android apps for that
- 00:14:03 if you want to build ios apps if you
- 00:14:05 want to test your app on ios and
- 00:14:06 ultimately build it for that platform
- 00:14:09 you need to install xcode which is
- 00:14:11 apple's
- 00:14:12 development ide but also a absolutely
- 00:14:16 required tool for building ios apps
- 00:14:18 even if you use flutter and no native
- 00:14:20 code for that
- 00:14:21 so install xcode by downloading it from
- 00:14:24 the mac
- 00:14:25 app store and once you got it installed
- 00:14:28 you need to make sure that you can use
- 00:14:30 the so-called xcode command line tools
- 00:14:33 and this can be done by simply copy and
- 00:14:36 pasting
- 00:14:36 this command into your terminal so you
- 00:14:39 can simply run this
- 00:14:41 you might be prompted to enter your
- 00:14:43 password there
- 00:14:45 and then it might or might not do
- 00:14:47 something depending on whether you
- 00:14:49 already configured this
- 00:14:50 it might prompt you to accept the
- 00:14:52 license once you completed this step
- 00:14:55 you can continue to step number three
- 00:14:58 and execute this command
- 00:14:59 to accept the license agreements of
- 00:15:02 xcode build which is the build tool
- 00:15:04 we're going to use
- 00:15:05 now here you can simply scroll to the
- 00:15:06 bottom which can be sped up
- 00:15:08 by hitting space a couple of times
- 00:15:12 and then type agree down there
- 00:15:15 now with that out of the way we can
- 00:15:16 continue and we can bring up the ios
- 00:15:19 simulator
- 00:15:20 which simply is iphone running on our
- 00:15:22 machine
- 00:15:24 it can be started with this command you
- 00:15:26 could also start it from within the
- 00:15:28 xcode by the way but i will simply start
- 00:15:30 it with this command
- 00:15:31 open dash a simulator with a capital
- 00:15:35 s and now what this should do is
- 00:15:38 it should bring up this ios simulator
- 00:15:42 here
- 00:15:42 now this is the device running you can
- 00:15:44 change the type of
- 00:15:46 phone you're emulating here from that
- 00:15:48 menu device
- 00:15:49 and then ios and then choose your
- 00:15:52 favorite device here
- 00:15:53 and now with that up and running what
- 00:15:55 you can do is you can start your flutter
- 00:15:58 app
- 00:15:58 by running flutter run in the command
- 00:16:01 prompt
- 00:16:02 now for that we need a flutter app
- 00:16:05 though right
- 00:16:06 because right now we only installed
- 00:16:07 flutter but we haven't set up a flutter
- 00:16:09 app a new project
- 00:16:11 so let's quickly do that and for that
- 00:16:13 you should first of all navigate
- 00:16:14 into the folder where you want to create
- 00:16:17 your flutter app
- 00:16:18 once you navigate it into that folder
- 00:16:20 where you want to create your new
- 00:16:22 flutter project run flutter create
- 00:16:25 and then the name for example first
- 00:16:27 underscore app
- 00:16:28 important this project name must not
- 00:16:31 contain dashes or white spaces
- 00:16:33 it should be using underscores instead
- 00:16:36 or would be one word only
- 00:16:38 hit enter and this will now set up a new
- 00:16:40 flatter project
- 00:16:42 in that specified location a new
- 00:16:44 subfolder which holds that project to be
- 00:16:46 precise
- 00:16:47 can take a couple of seconds
- 00:16:50 and once it's done you can navigate into
- 00:16:53 this newly created folder
- 00:16:54 in my case it's named first underscore
- 00:16:56 app and then hit
- 00:16:58 flutter run enter this hit enter and
- 00:17:01 with the ios simulator up and running
- 00:17:04 you should be able to see that flutter
- 00:17:06 app
- 00:17:06 on that ios simulator momentarily
- 00:17:10 the first build or the first time you
- 00:17:12 run this can take a couple of seconds
- 00:17:14 longer by the way
- 00:17:16 here we are now important keep that
- 00:17:18 process running don't quit it
- 00:17:20 you could quit it with control c but you
- 00:17:23 want to keep that running so that you
- 00:17:24 can always
- 00:17:25 rebuild your project and instantly ship
- 00:17:28 that new version to the device
- 00:17:30 whenever you change something in your
- 00:17:31 code so with that
- 00:17:34 you should see this your first flutter
- 00:17:37 app running on the iphone
- 00:17:39 and you can hit that plus button to see
- 00:17:41 a counter that is
- 00:17:42 incremented this is an app the flutter
- 00:17:45 tool created for you
- 00:17:46 we of course didn't write any code yet
- 00:17:49 now that's cool
- 00:17:50 and we will actually edit this a little
- 00:17:52 bit to see how we can well work with
- 00:17:54 that first flutter app
- 00:17:56 but obviously we also want to build for
- 00:17:59 android right
- 00:18:00 so let's go back to these installation
- 00:18:02 docs we're done with the ios setup here
- 00:18:04 the simulator at least now if you want
- 00:18:06 to deploy to a real ios
- 00:18:08 device you can follow these steps here
- 00:18:12 you will essentially need to plug in
- 00:18:14 your real iphone
- 00:18:16 then also again execute these steps to
- 00:18:19 install homebrew and then
- 00:18:20 these extra tools which you need to be
- 00:18:22 able to ship
- 00:18:24 your app to a real iphone and once
- 00:18:27 you're done with
- 00:18:28 that you can continue with these steps
- 00:18:30 and you will need to do some tweaking
- 00:18:32 in xcode to be able to ship your app to
- 00:18:36 your real device
- 00:18:37 now that is something i'll come back to
- 00:18:39 later in this course
- 00:18:41 when we will actually test this on a
- 00:18:43 real device
- 00:18:44 and also deploy the app at the end but
- 00:18:47 again
- 00:18:47 feel free to already go through these
- 00:18:49 steps they're really simple
- 00:18:50 if you want to run this on a real device
- 00:18:53 now i'll move on to
- 00:18:54 android for now and for that we will
- 00:18:57 need
- 00:18:57 android studio just like xcode is the
- 00:19:00 official ide
- 00:19:01 and contains all the build tools for ios
- 00:19:04 apps
- 00:19:05 android studio is the same for android
- 00:19:07 so
- 00:19:08 click that link to be forwarded to the
- 00:19:10 download page of android studio
- 00:19:13 and on that page it should automatically
- 00:19:15 present you
- 00:19:16 the mac os download so you can simply
- 00:19:19 hit
- 00:19:19 download android studio here accept
- 00:19:21 these license agreements and well then
- 00:19:24 download
- 00:19:25 store it is in any folder of your choice
- 00:19:28 and this again is a little bit of a
- 00:19:30 bigger file
- 00:19:31 so let's wait for this to finish before
- 00:19:34 we continue
- 00:19:35 now the download did finish you can then
- 00:19:38 simply execute that file and it will
- 00:19:40 launch an installer for you
- 00:19:42 i'll be able to close the ios simulator
- 00:19:44 here
- 00:19:46 now that android studio installer is
- 00:19:49 pretty straightforward on mac
- 00:19:51 just drag that into that applications
- 00:19:53 folder
- 00:19:55 and this will copy or install that
- 00:19:58 tool in that folder which again will
- 00:20:00 take a couple of seconds
- 00:20:01 since it also unpacks that folder and
- 00:20:04 once you are done with that
- 00:20:06 let's go back to the flutter
- 00:20:08 installation page
- 00:20:10 once you're done with that you need to
- 00:20:12 start
- 00:20:13 android studio and go through the setup
- 00:20:15 wizard to configure everything and
- 00:20:17 install everything you need
- 00:20:19 now you could also be getting a security
- 00:20:21 warning that the opening of android
- 00:20:23 studio was blocked because it was from
- 00:20:25 an
- 00:20:26 um well from the internet not from an
- 00:20:28 identified developer
- 00:20:30 you can then open it anyways through the
- 00:20:32 mac security and privacy settings
- 00:20:36 and ultimately this should bring up this
- 00:20:38 setup wizard
- 00:20:39 now click next on the first screen click
- 00:20:42 custom
- 00:20:42 on the next screen next again now here
- 00:20:45 you can choose your editor
- 00:20:47 theme if you want to have the light or
- 00:20:49 the dark one you don't need to use
- 00:20:51 android studio as an editor for this
- 00:20:54 course and actually i
- 00:20:55 won't but you can so i'll go with
- 00:20:58 darcula here
- 00:20:59 but that is totally up to you now on the
- 00:21:01 next screen make sure to also check
- 00:21:03 android virtual device here under the
- 00:21:05 installation options
- 00:21:08 the default installation path then
- 00:21:09 should be all right click next
- 00:21:11 and finish and now this will download a
- 00:21:14 bunch of things
- 00:21:15 and install all the sdks and tools
- 00:21:18 you need to develop android apps and
- 00:21:21 these will be used behind the scenes by
- 00:21:23 flutter which is why we need them
- 00:21:26 so let me fast forward until this is
- 00:21:29 also done
- 00:21:30 now by the way this can take a couple of
- 00:21:32 minutes so don't worry if it takes a bit
- 00:21:34 longer
- 00:21:34 it downloads and installs quite a lot of
- 00:21:36 things
- 00:21:38 now the setup finished for me here so
- 00:21:40 let's click finish
- 00:21:42 and thereafter you can click on open an
- 00:21:44 existing android studio project
- 00:21:47 now there simply navigate to the folder
- 00:21:50 where you just created your new flutter
- 00:21:52 app
- 00:21:53 in my case that's that first underscore
- 00:21:56 app
- 00:21:56 folder select the whole folder and click
- 00:21:59 open
- 00:22:00 and this will bring up android studio
- 00:22:03 with that project
- 00:22:04 opened now when you open it for the
- 00:22:06 first time
- 00:22:07 it will actually scan that folder so
- 00:22:10 let's wait for this to
- 00:22:11 finish and it should actually suggest
- 00:22:14 you two things
- 00:22:15 down there it finds something about a
- 00:22:18 plugin
- 00:22:18 and there you can simply expand this and
- 00:22:20 click on configure plugins
- 00:22:22 it actually also shows you something
- 00:22:24 about the dart files we ignore this for
- 00:22:26 now
- 00:22:27 so now choose that flutter plugin and
- 00:22:29 click ok
- 00:22:30 and thereafter click yes to also install
- 00:22:33 that dark plugin for which it's asking
- 00:22:35 up there
- 00:22:41 thereafter simply restart now once you
- 00:22:44 restart it
- 00:22:45 you may get a message at the bottom
- 00:22:48 here regarding ide and plugin updates if
- 00:22:50 you don't that's fine too
- 00:22:51 in my case i do get one so i'll simply
- 00:22:54 update now to install the latest
- 00:22:56 versions of all the sdks and build tools
- 00:22:58 i might need
- 00:22:59 and that again will get downloaded which
- 00:23:02 again will take a couple of seconds
- 00:23:04 and now with all that done let me click
- 00:23:06 finish here
- 00:23:08 and now this is our flutter project now
- 00:23:10 i will open this in a different ide
- 00:23:12 where it's also a bit easier to read in
- 00:23:14 a second for now we won't
- 00:23:16 work on that code here instead let's run
- 00:23:19 this on an
- 00:23:20 emulator for that we can simply go to
- 00:23:23 tools and then avd manager that stands
- 00:23:26 for
- 00:23:26 android virtual device let's open that
- 00:23:30 tool
- 00:23:30 and here i actually got some
- 00:23:32 pre-configured devices
- 00:23:34 you should at least have one that nexus
- 00:23:37 or
- 00:23:38 some other device which is created with
- 00:23:39 the installation you can always create a
- 00:23:42 new virtual device by clicking that
- 00:23:44 button here at the bottom
- 00:23:46 and then you can choose which device you
- 00:23:48 want to use let's say the pixel
- 00:23:50 2 continue choose your api version
- 00:23:53 now typically the highest one is a good
- 00:23:56 choice or
- 00:23:57 the one selected by default i should say
- 00:23:59 not necessarily the cutting edge one but
- 00:24:01 this one
- 00:24:02 click next again now here on emulated
- 00:24:06 performance
- 00:24:07 you should choose the hardware emulation
- 00:24:10 for a faster emulator the other settings
- 00:24:14 should be fine
- 00:24:16 simply hit finish and this should create
- 00:24:18 that new emulator and you can then start
- 00:24:21 it by clicking on that play button on
- 00:24:23 the very right here
- 00:24:24 now this will bring up your android
- 00:24:27 emulator
- 00:24:28 now we can of course use that emulator
- 00:24:30 to run our flutter app there
- 00:24:32 too and to run it what we need to do is
- 00:24:35 we need to go back to that command line
- 00:24:37 where we previously already ran it
- 00:24:39 on the iphone and repeat that flutter
- 00:24:42 run command if you still got the old one
- 00:24:44 running
- 00:24:45 which you probably don't have if you
- 00:24:47 shut down the old simulator
- 00:24:48 you can always quit the running process
- 00:24:50 with ctrl
- 00:24:52 c so let's hit flutter run to run it on
- 00:24:55 our
- 00:24:55 android emulator once that emulator did
- 00:24:58 boot up
- 00:24:59 and it will build the project with the
- 00:25:01 help of the android sdk
- 00:25:03 that was installed together with android
- 00:25:05 studio
- 00:25:06 and that first build process can again
- 00:25:09 take a couple of seconds
- 00:25:10 subsequent ones will be faster and now
- 00:25:13 it should be up and running
- 00:25:14 let's do it and there it is this is our
- 00:25:17 device
- 00:25:18 and this is our flutter app and we can
- 00:25:19 click the plus button to
- 00:25:21 increment this counter awesome so this
- 00:25:24 is how we install
- 00:25:25 flutter and run it on both the ios and
- 00:25:28 android emulators
- 00:25:30 now if you want to run it on real
- 00:25:31 devices you can follow the steps
- 00:25:33 outlined in the documentation
- 00:25:34 but of course we'll also run it together
- 00:25:37 on the real device
- 00:25:38 later in this course for now let's focus
- 00:25:41 on the editor
- 00:25:42 with which we're going to work on this
- 00:25:43 code
- 00:25:48 i will not use the android studio editor
- 00:25:51 though you can absolutely do that
- 00:25:53 there's nothing wrong with it it's a
- 00:25:55 fully fledged
- 00:25:56 ide with the flutter plugin you can work
- 00:25:58 in it
- 00:25:59 and if you want to use that you can
- 00:26:01 follow along through the entire course
- 00:26:02 with that id
- 00:26:03 without problems i'll quit it though
- 00:26:06 because i have another id which i like
- 00:26:08 more
- 00:26:09 and that's visual studio code you
- 00:26:11 install it from codevisualstudio.com
- 00:26:14 and it's a free ide just like android
- 00:26:17 studio
- 00:26:17 it should automatically present you the
- 00:26:19 right download option
- 00:26:21 for a mac and you can simply well
- 00:26:23 download it then
- 00:26:25 and once you did download it you will
- 00:26:27 have
- 00:26:28 a file which you can execute and which
- 00:26:30 will walk you through the installer
- 00:26:32 the installation should be pretty
- 00:26:34 straightforward there's nothing special
- 00:26:36 on it or nothing tricky on it once you
- 00:26:40 did install visual studio you can
- 00:26:43 open it run it and then in the starting
- 00:26:45 screen simply choose
- 00:26:46 open folder or choose file open
- 00:26:50 to open your flutter project so that is
- 00:26:52 what i'll do
- 00:26:54 open that first app folder and this will
- 00:26:56 now
- 00:26:57 open flatter in well that ide
- 00:27:01 now i will actually use this id and also
- 00:27:04 this
- 00:27:04 look of the ide which is the dark theme
- 00:27:07 you can change to look
- 00:27:09 under code preferences
- 00:27:12 color themes but i will install some
- 00:27:15 extra extensions to make working with
- 00:27:18 flutter
- 00:27:19 a bit more pleasant and that extension
- 00:27:22 can be added
- 00:27:23 by going to view extensions or using
- 00:27:26 that shortcut
- 00:27:27 or using that sidebar you will probably
- 00:27:29 see here on the left
- 00:27:32 extensions are simply add-ons to visual
- 00:27:34 studio code which lets
- 00:27:35 us enhance the coding experience and
- 00:27:37 there you should simply search for
- 00:27:39 flutter
- 00:27:40 to find your official flutter plugin or
- 00:27:42 extension
- 00:27:43 click install there and this will also
- 00:27:46 install the dart extension as a
- 00:27:48 dependency
- 00:27:49 once you did install it you can hit
- 00:27:51 reload to reload visual studio code with
- 00:27:53 that extension added
- 00:27:55 there's one extra extension i will use
- 00:27:57 throughout the course which is totally
- 00:27:59 optional
- 00:28:00 and that's the material icon theme now
- 00:28:02 that's not related to
- 00:28:03 flutter it just makes the icons look
- 00:28:06 nicer i already got it installed
- 00:28:08 you can install it from this page and
- 00:28:11 once you did install
- 00:28:12 that but more important the flutter one
- 00:28:15 you can switch back to the explorer
- 00:28:17 here with that shortcut or by clicking
- 00:28:19 in the menu
- 00:28:20 and you're back in your project
- 00:28:21 structure and now you're well prepared
- 00:28:23 to work with flutter
- 00:28:25 and for example here in our main dart
- 00:28:28 file we can manipulate our first app
- 00:28:31 by for example going down to the
- 00:28:33 increment counter method here
- 00:28:35 and changing that counter plus plus
- 00:28:37 thing to counter equals
- 00:28:40 counter plus 2. this should now increase
- 00:28:42 the counter by
- 00:28:43 two on every click now the very cool
- 00:28:45 thing is you can hit
- 00:28:47 save here and then go back to your
- 00:28:50 command prompt where you ran flutter run
- 00:28:53 and simply hit r with that flatter run
- 00:28:56 process running so don't quit it
- 00:28:58 hit r whilst it is running and it will
- 00:29:00 hot
- 00:29:01 reload your flutter app which means it
- 00:29:03 will reload it
- 00:29:04 on the fly on the emulator without the
- 00:29:07 need to rebuild it
- 00:29:09 if that gets stuck somehow you can press
- 00:29:12 shift
- 00:29:12 r for a full rebuild and reload still
- 00:29:15 with that process running
- 00:29:17 so let's go back to our app and it looks
- 00:29:20 like nothing changed we even have the
- 00:29:22 old counter
- 00:29:22 but if we click the plus now it
- 00:29:24 increases by two
- 00:29:26 and that's already showing how cool it
- 00:29:28 is to work with flutter and how easy it
- 00:29:30 is to develop with it
- 00:29:31 with that hot reloading and this also is
- 00:29:34 the setup i will use throughout the
- 00:29:36 course
- 00:29:36 and i will teach you all about flutter
- 00:29:39 dart and some tricks
- 00:29:40 with the ide throughout this course now
- 00:29:43 let's see how that works for windows
- 00:29:45 or if that doesn't matter to you because
- 00:29:47 you're using mac only
- 00:29:48 let's continue with the chords and dive
- 00:29:50 deeper into flutter
- 00:29:56 in the last video we installed flutter
- 00:29:58 for mac now if you're using windows
- 00:30:01 let's now install it for windows 2. if
- 00:30:03 you're using mac only you can therefore
- 00:30:05 skip this video
- 00:30:07 so to install flutter on windows first
- 00:30:09 of all let's visit flutter.io
- 00:30:12 click on get started there and then
- 00:30:14 choose install on windows
- 00:30:16 there you will see all the installation
- 00:30:18 steps in detail
- 00:30:20 and i strongly recommend all going
- 00:30:22 through these step by step
- 00:30:24 along with the video because for one
- 00:30:27 they can't change in one or the other
- 00:30:30 detail
- 00:30:31 in the future and then this is great to
- 00:30:33 see or easy to see in that written form
- 00:30:36 and additionally it's easy to miss a
- 00:30:38 step and therefore this is a great
- 00:30:40 companion for this video
- 00:30:43 so first of all let's have a look at the
- 00:30:44 system requirements
- 00:30:46 we install flutter on our machine we
- 00:30:48 need windows 7
- 00:30:50 or higher the disk space which is
- 00:30:52 mentioned here
- 00:30:53 and important one of these two tools
- 00:30:55 powershell or git for windows
- 00:30:58 now git is a versioning system and even
- 00:31:00 if you don't use it actively
- 00:31:02 flutter does use it so here i'll install
- 00:31:05 git for windows by clicking on that link
- 00:31:08 then we have the chance to download that
- 00:31:11 git tool from
- 00:31:12 that git page here it should
- 00:31:15 automatically give you the right
- 00:31:16 download for your machine
- 00:31:18 download it and then walk through the
- 00:31:21 installer
- 00:31:22 now in the installer you can choose a
- 00:31:24 place where you want to install git
- 00:31:26 then simply hit next and well install
- 00:31:29 that tool
- 00:31:31 now very important you click next a
- 00:31:33 couple of times
- 00:31:34 and most of the default settings are
- 00:31:36 fine
- 00:31:38 one important thing to note is that on
- 00:31:40 this screen here
- 00:31:41 you should use use get from the windows
- 00:31:44 command prompt don't use one of the
- 00:31:46 other two options
- 00:31:47 use the middle one here this is also
- 00:31:50 mentioned in the official docs
- 00:31:53 now with that hit next a couple of times
- 00:31:55 and leave all the other defaults
- 00:31:57 and with all that simply hit next one
- 00:32:00 last time and it will install git
- 00:32:02 on your machine with that you're fine
- 00:32:04 you can now close this and continue
- 00:32:06 in these setup instructions
- 00:32:12 the next step is to actually install the
- 00:32:14 flutter sdk
- 00:32:16 which you can get from this download
- 00:32:18 link here
- 00:32:19 now important the version of flutter of
- 00:32:21 course will change in the future
- 00:32:23 right now it's 0.3.2.beta
- 00:32:26 it's production ready already and the
- 00:32:28 code you learn
- 00:32:29 in this course will still be all correct
- 00:32:31 in the future even if you are
- 00:32:33 downloading a different version
- 00:32:34 but make sure to download the version
- 00:32:36 you are seeing here
- 00:32:37 so whatever version that is for you
- 00:32:40 so this will now always be downloaded
- 00:32:43 will take a couple of seconds since it's
- 00:32:44 quite a big
- 00:32:45 file and once it is downloaded you can
- 00:32:48 extract this folder
- 00:32:50 into the place where you want to install
- 00:32:53 that flutter tool
- 00:32:54 now important the flutter tool is
- 00:32:57 not your project for your mobile app
- 00:33:00 it's a sdk a software development kit
- 00:33:04 which you install globally on your
- 00:33:06 machine and which you will use from
- 00:33:08 different places on your machine
- 00:33:10 to create new flatter projects and to
- 00:33:13 work with the ones you created so to
- 00:33:15 build them to run them on an emulator
- 00:33:17 things like that
- 00:33:23 so unzip flutter into that directory
- 00:33:26 and once you unzipped it you can go into
- 00:33:29 that
- 00:33:30 directory and in my case here i'll also
- 00:33:33 move all the files
- 00:33:34 up one folder so that they're all
- 00:33:36 directly in the flutter folder
- 00:33:42 and then you can execute that flutter
- 00:33:45 console.bat file here
- 00:33:47 now this will open up a command prompt
- 00:33:50 which
- 00:33:50 already uses flutter and you could stop
- 00:33:53 here and continue with the flooded
- 00:33:55 commands and with
- 00:33:57 bringing up your android emulator and so
- 00:33:59 on and always open
- 00:34:01 that tool here to run the flutter
- 00:34:03 commands which you need to run or build
- 00:34:05 your app
- 00:34:06 however i want to be able to use the
- 00:34:09 normal command prompt
- 00:34:10 so let's close the flatter console here
- 00:34:14 and let's move on and make sure that we
- 00:34:16 can use the flutter commands
- 00:34:18 from the normal windows command prompt
- 00:34:21 for that we'll need to update our path
- 00:34:24 now the path that simply is a global
- 00:34:26 variable which windows uses
- 00:34:28 to find the tools we can use from the
- 00:34:31 command line
- 00:34:32 and since we picked a custom folder
- 00:34:35 where we installed flutter or where we
- 00:34:37 unpacked it to
- 00:34:38 we need to make windows aware of where
- 00:34:40 that is
- 00:34:42 you do that by opening your control
- 00:34:44 panel
- 00:34:45 and then going to user user accounts
- 00:34:49 and there simply click on change my
- 00:34:52 environment variables
- 00:34:54 now in the window which opens you should
- 00:34:56 find a path
- 00:34:57 entry which you can select and where you
- 00:35:00 then can click
- 00:35:01 edit now here you can add new locations
- 00:35:04 of tools you want to be able to execute
- 00:35:06 to that path by clicking on new here
- 00:35:10 and then here you need to enter the path
- 00:35:13 to your flutter folder
- 00:35:15 so the folder you unpacked simply
- 00:35:18 go into your windows explorer and there
- 00:35:21 navigate into the bin
- 00:35:23 subfolder to be precise that is what you
- 00:35:25 need
- 00:35:26 copy the path to that bin subfolder and
- 00:35:30 add it to your path variable by clicking
- 00:35:33 new
- 00:35:33 adding it to that empty blank space
- 00:35:36 which opens up
- 00:35:37 and thereafter hitting ok now you're
- 00:35:41 prepared to run flatter commands
- 00:35:43 from the normal command prompt click ok
- 00:35:46 and make sure to close any command
- 00:35:49 prompts you might have opened already
- 00:35:51 restart windows if you're facing issues
- 00:35:53 thereafter
- 00:35:55 and once you did all that you can bring
- 00:35:57 up the normal command prompt
- 00:35:59 and simply enter flutter there
- 00:36:02 now this might show you a warning
- 00:36:04 regarding the installation being a bit
- 00:36:06 older you can ignore that because we
- 00:36:08 actually did just install the latest
- 00:36:10 version so that will be all right
- 00:36:12 but the fact that you're seeing this and
- 00:36:14 not something like
- 00:36:16 flutter not recognized means that we did
- 00:36:18 successfully add it to our path
- 00:36:21 and that we can use that flutter command
- 00:36:23 line tool from our command prompt
- 00:36:26 now flutter is now available
- 00:36:29 the next step we have to do is we have
- 00:36:32 to set up
- 00:36:32 android studio this is the official sdk
- 00:36:36 provided by google for building android
- 00:36:40 apps
- 00:36:41 and whilst we will not write native code
- 00:36:43 with it
- 00:36:44 it includes all the sdks and build tools
- 00:36:47 flutter will need too so simply go to
- 00:36:53 com slash developer.android.com or use
- 00:36:54 the link you find in the flatter
- 00:36:56 installation documentation
- 00:36:58 and download the android studio version
- 00:37:00 there it should automatically give you
- 00:37:02 the right version for your operating
- 00:37:04 system
- 00:37:05 you need to accept the agreement before
- 00:37:07 you can continue
- 00:37:08 and with that the download will start
- 00:37:11 and it will
- 00:37:11 also take a while since it's all the
- 00:37:13 quite a big download
- 00:37:15 so let me fast forward to the point
- 00:37:17 where this is done
- 00:37:20 now once the download did finish simply
- 00:37:22 execute the well
- 00:37:23 executable you got and the installer
- 00:37:25 will start
- 00:37:26 now there you can continue make sure
- 00:37:30 to choose android virtual device
- 00:37:33 as a component you want to install
- 00:37:35 though that's important that you tick
- 00:37:36 that
- 00:37:37 thereafter you can choose the location
- 00:37:39 where you want to install
- 00:37:41 android studio and you can use the
- 00:37:43 default here or
- 00:37:44 pick your own location on your machine
- 00:37:46 and then you can simply hit next
- 00:37:48 now this will again take a couple of
- 00:37:50 seconds
- 00:37:51 and once it's done you can start the
- 00:37:54 android studio
- 00:37:56 and for the first time you start it a
- 00:37:58 wizard
- 00:37:59 will come up which allows you to
- 00:38:01 configure it
- 00:38:03 now in that wizard hit next and then
- 00:38:06 choose
- 00:38:07 custom here and the next step is that
- 00:38:09 you can choose your ui theme
- 00:38:11 now that's most important if you want to
- 00:38:13 use android studio to build your flutter
- 00:38:16 apps
- 00:38:16 which you can however i will use a
- 00:38:18 different
- 00:38:19 ide in this course and i will go with
- 00:38:21 the dark theme here but of course you
- 00:38:23 can choose your favorite look
- 00:38:26 in the next step it's important that you
- 00:38:28 check android virtual device that this
- 00:38:30 option is ticked because
- 00:38:32 we will need to be able to bring up such
- 00:38:34 virtual devices
- 00:38:35 with that ticked choose your android sdk
- 00:38:38 location
- 00:38:39 use the default or create your own path
- 00:38:42 and thereafter
- 00:38:43 simply hit next
- 00:38:48 now this will install a couple of things
- 00:38:50 and you can start installation by
- 00:38:52 hitting finish here
- 00:38:53 this will actually take quite long
- 00:38:55 because it downloads and installs a lot
- 00:38:57 of packages
- 00:38:58 so don't worry if this takes a couple of
- 00:39:01 minutes maybe even
- 00:39:02 20 minutes or something like this and i
- 00:39:04 will be back
- 00:39:05 once it's done for me once the
- 00:39:08 installation did finish
- 00:39:09 you can well close the installer and
- 00:39:12 then
- 00:39:13 bring up android studio again now
- 00:39:16 here you can open an existing
- 00:39:19 android studio project which would be
- 00:39:21 your flutter
- 00:39:22 app you're working on but we don't have
- 00:39:25 such a app yet
- 00:39:26 so our next step actually is to create
- 00:39:28 such a app however
- 00:39:30 we will need an emulator to view it
- 00:39:33 so let's make sure we fulfill all
- 00:39:35 requirements for that
- 00:39:36 you can see them here in the official
- 00:39:39 docs
- 00:39:40 and by the way if you want to install
- 00:39:43 your app on a real device
- 00:39:45 that is something we'll all to do later
- 00:39:47 in the course and you can of course
- 00:39:48 already go through the steps you see
- 00:39:50 here if that's important to you right
- 00:39:51 now already
- 00:39:52 but again we'll do this together later
- 00:39:54 in the course for the majority of the
- 00:39:56 course we will work on the
- 00:39:57 emulator though so there on the emulator
- 00:40:00 you see that it's important that we have
- 00:40:02 hardware acceleration enabled on our
- 00:40:04 machine click that link to learn more
- 00:40:06 about it and see how to
- 00:40:08 turn it on and thereafter we can go back
- 00:40:12 to android studio
- 00:40:13 and now we need that flutter project to
- 00:40:15 continue
- 00:40:16 so back to the command prompt there you
- 00:40:19 should now
- 00:40:20 navigate into the folder where you want
- 00:40:22 to create your new flutter project
- 00:40:25 you can navigate around in windows with
- 00:40:27 the cd command to change the
- 00:40:29 directory you're in in the command
- 00:40:31 prompt
- 00:40:33 now make sure to create a folder and
- 00:40:34 navigate into that folder where you want
- 00:40:36 to store your flutter app
- 00:40:38 and once you're in that folder you can
- 00:40:40 create a new flutter
- 00:40:42 application and project by running
- 00:40:44 flutter
- 00:40:45 create and then the name of your project
- 00:40:48 now important that name must not contain
- 00:40:52 a dash or something like that also not a
- 00:40:54 white space
- 00:40:55 words should be separate with
- 00:40:56 underscores or you simply use one word
- 00:40:59 only so flutter create first underscore
- 00:41:02 app
- 00:41:02 is my command here to create this
- 00:41:04 project and now
- 00:41:06 this will add a new folder in the
- 00:41:08 location you're in in the command prompt
- 00:41:10 and configure your first flutter project
- 00:41:12 in there
- 00:41:13 as you can see it creates a couple of
- 00:41:15 files and once it's done with all that
- 00:41:17 you can open the project in android
- 00:41:19 studio by clicking on
- 00:41:21 open an existing android studio project
- 00:41:24 and there you should navigate to that
- 00:41:26 folder you just created
- 00:41:28 and open it there in the flatter folder
- 00:41:31 my case so
- 00:41:32 basically open that project you just
- 00:41:34 created first underscore app in my case
- 00:41:37 this will open it in android studio and
- 00:41:40 before we do anything there
- 00:41:42 let's bring up that virtual device
- 00:41:45 you can do that by in android studio
- 00:41:49 going to tools and then avd manager
- 00:41:53 which stands for android virtual device
- 00:41:55 manager
- 00:41:57 and in the window which then opens up
- 00:41:59 you can
- 00:42:00 start a new virtual device by clicking
- 00:42:03 on to
- 00:42:04 create virtual device you should also
- 00:42:06 have one by default which you can use
- 00:42:07 but let me show you how to create a new
- 00:42:09 one
- 00:42:10 there you choose your blueprint
- 00:42:12 basically regarding the general hardware
- 00:42:14 and layout profile i'll go with the
- 00:42:17 pixel 2 here
- 00:42:19 on the next screen you choose the image
- 00:42:21 the android version you want to use
- 00:42:23 and i recommend not going with the
- 00:42:25 cutting edge version but using the
- 00:42:27 latest
- 00:42:27 stable version in my case oreo api level
- 00:42:31 27
- 00:42:33 typically that's the one which is
- 00:42:34 selected by default
- 00:42:36 hit next again now on the next screen
- 00:42:39 make sure to choose
- 00:42:41 hardware acceleration from the graphics
- 00:42:44 drop down there
- 00:42:45 and you can have a look at the advanced
- 00:42:46 settings but you typically don't need to
- 00:42:48 change these
- 00:42:50 and with that all done you can finish
- 00:42:52 that and create that new virtual device
- 00:42:56 now with it created you can start it by
- 00:42:59 clicking on that play button
- 00:43:00 on the right and this will open the
- 00:43:02 virtual device
- 00:43:04 on your screen it will bring up a
- 00:43:06 android phone
- 00:43:07 on your machine so to say now
- 00:43:11 with that running we can't run our
- 00:43:13 flutter app yet
- 00:43:14 because we still need to do some things
- 00:43:18 for one we need to install the missing
- 00:43:20 dependencies the missing plugins
- 00:43:23 for that click on install plugins here
- 00:43:26 at the top where it
- 00:43:27 tells you about the missing dart plugin
- 00:43:30 you could by the way also skip this if
- 00:43:32 you already
- 00:43:33 installed the flutter plug-in but here i
- 00:43:35 do it in two separate steps
- 00:43:36 so install that dart plug-in
- 00:43:40 once the installer is done you need to
- 00:43:42 restart android studio
- 00:43:44 and once you restart it you should
- 00:43:46 actually get a message here
- 00:43:49 at the bottom where it suggests you a
- 00:43:52 new plugin
- 00:43:53 expand that message and click on
- 00:43:54 configure plugins
- 00:43:56 and there it will suggest a flutter
- 00:43:58 plugin
- 00:43:59 simply accept this by clicking ok and
- 00:44:02 now it will install the flutter plugin
- 00:44:04 too
- 00:44:04 and that would have installed the dart
- 00:44:06 plugin with it so you can actually do
- 00:44:08 that in one step only
- 00:44:10 once this is done you need to restart
- 00:44:12 the ide one more time
- 00:44:14 so let's do that let's restart the ide
- 00:44:16 again
- 00:44:20 and now we have android studio
- 00:44:22 configured
- 00:44:23 to support flutter now
- 00:44:26 we still don't see our emulator here at
- 00:44:29 the top and therefore we still can't
- 00:44:31 start our application
- 00:44:33 let's quit the emulator for now
- 00:44:36 and to make it work first of all go back
- 00:44:39 to the setup instructions and make sure
- 00:44:41 to install that google usb driver now
- 00:44:43 that should only be important for
- 00:44:45 running it on a real device
- 00:44:47 but it still doesn't hurt to set it up
- 00:44:49 already so that it will work
- 00:44:50 later so click on that link you see
- 00:44:53 there and install the usb
- 00:44:55 driver you can do that from within
- 00:44:57 android studio
- 00:44:58 by going back into it and they're going
- 00:45:01 to
- 00:45:02 tools sdk manager and
- 00:45:05 in the sdk manager go to sdk tools and
- 00:45:08 choose google usb
- 00:45:09 driver there hit ok thereafter or apply
- 00:45:12 and install it you also need to accept
- 00:45:16 the license agreements there
- 00:45:18 now with it installed you will need to
- 00:45:22 also do one more thing if you installed
- 00:45:25 your android sdk in a different
- 00:45:29 place on your operating system than the
- 00:45:31 one suggested during the wizard
- 00:45:33 which i did you need to add one other
- 00:45:36 environment variable
- 00:45:37 you can also see that if you go back to
- 00:45:40 the command prompt and run
- 00:45:42 flutter doctor a tool which tells you
- 00:45:44 what's missing
- 00:45:45 here it tells me that it's unable to
- 00:45:47 locate the android sdk
- 00:45:49 and therefore i will go back to my
- 00:45:52 control panel
- 00:45:53 and there to user accounts user accounts
- 00:45:56 and then change my environment variables
- 00:45:58 and first of all we need to add a brand
- 00:46:00 new variable so click
- 00:46:01 new here and then name that variable and
- 00:46:05 the name is important
- 00:46:06 android underscore home all uppercase
- 00:46:09 make sure to not add a typo here now
- 00:46:12 with that name defined you need to
- 00:46:14 define a value
- 00:46:16 and that simply is a path pointing to
- 00:46:19 the android sdk
- 00:46:20 you can click browse directory here to
- 00:46:22 choose the android sdk location
- 00:46:25 and there simply choose the location you
- 00:46:27 selected during
- 00:46:28 the wizard or in the wizard which opened
- 00:46:31 or which ran when you opened android
- 00:46:33 studio
- 00:46:34 in my case it's the android folder it
- 00:46:36 should be this folder which has a
- 00:46:38 platforms emulator and so on subfolder
- 00:46:41 simply hit ok with the root folder
- 00:46:43 selected
- 00:46:44 and now you also need to add something
- 00:46:46 to your path variable
- 00:46:47 so select that again and click on edit
- 00:46:49 and there you need to add two
- 00:46:51 new entries the first one should be
- 00:46:55 percentage sign and then android home
- 00:46:58 so that variable name you just created
- 00:47:00 written exactly the same way
- 00:47:02 and then another percentage sign
- 00:47:05 backslash
- 00:47:06 tools and then you need to add one hour
- 00:47:09 entry which is
- 00:47:10 also percentage sign android home
- 00:47:14 backslash platform tools make sure it's
- 00:47:16 written exactly as you see it here in
- 00:47:18 the video
- 00:47:19 now with that added hit okay and restart
- 00:47:22 the command prompt
- 00:47:24 and now also restart your virtual device
- 00:47:26 by quitting it
- 00:47:27 potentially wiping the user data if
- 00:47:30 you're facing issues restarting it
- 00:47:32 and then hitting the green play button
- 00:47:34 again this will bring up the emulator
- 00:47:36 again
- 00:47:40 and now you should see it here in the
- 00:47:42 drop down selected
- 00:47:45 and now you can press that run button to
- 00:47:48 run your flutter app
- 00:47:50 on that virtual device now this
- 00:47:53 build process which will start it on the
- 00:47:56 device can take a couple of minutes when
- 00:47:58 you run it the first time
- 00:47:59 don't worry about that and once it's
- 00:48:02 done you should see your flutter app
- 00:48:04 running on that emulator and you can hit
- 00:48:06 the plus button here
- 00:48:08 to increment the counter pretty awesome
- 00:48:10 our flutter app
- 00:48:12 finally running on an emulator and of
- 00:48:14 course we'll change this app soon
- 00:48:17 now as i mentioned i won't use android
- 00:48:20 studio
- 00:48:21 as an editor here and therefore
- 00:48:24 i also want to show you a way of running
- 00:48:26 this without android studio
- 00:48:28 you can do that by going to the command
- 00:48:31 prompt
- 00:48:31 navigating into the folder where you
- 00:48:33 have your first app or
- 00:48:35 into this project folder you created and
- 00:48:37 in there
- 00:48:38 you can run flutter run and this will
- 00:48:41 now
- 00:48:42 do the exact same as you did with the
- 00:48:44 command inside or with the click of the
- 00:48:46 button
- 00:48:46 inside android studio but without you
- 00:48:49 doing it through android studio it will
- 00:48:51 build the app
- 00:48:52 and ship it to your emulator and run it
- 00:48:54 there
- 00:48:55 and this is actually how i will run my
- 00:48:57 apps for the rest of this course since i
- 00:48:59 won't use android studio
- 00:49:00 you can use either approach however
- 00:49:03 using flutter run
- 00:49:04 will have advantages like the hot
- 00:49:05 reloading i'll introduce in a second
- 00:49:12 now which editor will i use then i will
- 00:49:16 use
- 00:49:16 visual studio code you can get it from
- 00:49:20 code.visualstudio.com
- 00:49:22 it's a free ide which also has an
- 00:49:25 extension that provides awesome flutter
- 00:49:27 support
- 00:49:28 you can download it from that page and
- 00:49:30 it will automatically give you the right
- 00:49:32 version for your operating system
- 00:49:34 and you can simply walk through the
- 00:49:36 installer it's pretty straightforward
- 00:49:38 nothing special about it simply install
- 00:49:40 the ide on your machine
- 00:49:43 now once you did install it in your
- 00:49:45 favorite location
- 00:49:46 you can start it and in the ide
- 00:49:49 you can then click open folder or
- 00:49:52 choose the open option from the file
- 00:49:55 menu in the top left corner
- 00:49:57 and simply choose that first underscore
- 00:49:59 app folder you created
- 00:50:01 now this is your flutter app and in
- 00:50:03 order to be able to work with that
- 00:50:05 really well we should add a so-called
- 00:50:08 extension
- 00:50:08 so a plug-in we can add to that ide to
- 00:50:11 add
- 00:50:12 extra functionalities you can install
- 00:50:14 extensions by clicking on this
- 00:50:16 icon on the left or selecting view
- 00:50:19 extensions in the menu at the top
- 00:50:22 and there simply search for flutter
- 00:50:25 install that extension you find here
- 00:50:27 it's the official flatter extension
- 00:50:29 and it will also install the dart
- 00:50:31 extension together with it because that
- 00:50:33 will be a dependency
- 00:50:35 and once it is installed you just need
- 00:50:37 to restart the ide
- 00:50:39 to have that installed now i will use
- 00:50:42 one extra extension throughout the
- 00:50:44 course and that's the material i can
- 00:50:46 theme that is not related to flutter
- 00:50:48 development
- 00:50:49 i just like the i can look i get with it
- 00:50:52 it's totally optional
- 00:50:53 i just want to show it here so that you
- 00:50:55 don't wonder why my icons look different
- 00:50:58 than the default icons
- 00:51:00 once you install that if you want it you
- 00:51:02 again can
- 00:51:03 reload the ide and with that
- 00:51:06 we can finally make a change to our
- 00:51:09 flutter code after i activated that new
- 00:51:12 theme
- 00:51:14 you can see your flutter code in the lib
- 00:51:16 folder of the project you opened
- 00:51:18 and there in the main.dart file you see
- 00:51:21 the code which is responsible for the
- 00:51:23 app which is currently running on the
- 00:51:24 emulator
- 00:51:26 there search the increment counter
- 00:51:30 the underscore increment counter method
- 00:51:33 and in set state change underscore
- 00:51:36 counter plus plus to underscore counter
- 00:51:40 equals underscore counter plus two
- 00:51:43 this should ensure that we actually
- 00:51:44 increase the counter by two every time
- 00:51:46 we hit the plus
- 00:51:47 not by one anymore with that change made
- 00:51:51 go back to the command prompt and make
- 00:51:54 sure that the flood
- 00:51:55 run process is still running don't quit
- 00:51:58 it
- 00:51:58 you could quit it with ctrl c but as
- 00:52:01 long as you are developing you should
- 00:52:03 keep it
- 00:52:03 running because then you can hit r with
- 00:52:07 that process running
- 00:52:08 to hot reload your app which means the
- 00:52:11 changes you added are pushed into the
- 00:52:13 app
- 00:52:13 without the need for it to rebuild now
- 00:52:16 sometimes this fails then you can press
- 00:52:19 shift r to do a full reload and a full
- 00:52:22 rebuild and you can quit that process
- 00:52:24 with ctrl c if you're done with
- 00:52:26 development for the day
- 00:52:27 so i pressed r and if i go back to
- 00:52:31 my emulator here you can see
- 00:52:34 that i can now increment by two
- 00:52:37 instead of one and this
- 00:52:40 is our first little change we will do
- 00:52:42 much more of course
- 00:52:44 but this is our windows setup finished
- 00:52:46 was quite a lot of work
- 00:52:47 but now we are prepared to continue and
- 00:52:50 dive
- 00:52:50 much deeper into flutter of course
- 00:52:57 we set up our environment and we created
- 00:53:00 and edited
- 00:53:01 our very first flutter app now before we
- 00:53:04 dive
- 00:53:04 way deeper into that in the next module
- 00:53:07 and the modules thereafter
- 00:53:09 let me briefly talk about some
- 00:53:10 alternatives flutter is of course not
- 00:53:12 the only way of creating
- 00:53:14 native mobile apps there are three
- 00:53:16 alternatives i want to discuss
- 00:53:18 the first one is that you write real
- 00:53:20 native apps by learning
- 00:53:22 java and android and swift objective c
- 00:53:25 for the respective platforms
- 00:53:27 the advantage of this is that you got
- 00:53:29 full access to all features
- 00:53:31 and you don't need to worry about
- 00:53:33 finding some workarounds to get
- 00:53:35 that feature to work in your app the
- 00:53:37 huge downside is that
- 00:53:39 you have to learn two completely
- 00:53:41 different languages
- 00:53:42 and that takes a lot of time and
- 00:53:44 possibly all the money
- 00:53:46 so this is a huge downside and flutter
- 00:53:49 can actually get you
- 00:53:50 to the same result so not the best
- 00:53:53 alternative maybe
- 00:53:54 except for cases where you have a very
- 00:53:56 specialized app where you absolutely
- 00:53:58 need that latest cutting edge feature
- 00:54:01 and you would end up writing a lot of
- 00:54:02 native code anyways
- 00:54:04 because you can connect flutter with
- 00:54:06 native code we'll cover that in the
- 00:54:07 course
- 00:54:08 so an alternative but flutter has a lot
- 00:54:11 of advantages
- 00:54:12 second alternative is that you create a
- 00:54:14 progressive web app
- 00:54:15 now you might not know what it is it's a
- 00:54:18 website essentially
- 00:54:19 it's not a native mobile app it's not
- 00:54:21 distributed through the app stores
- 00:54:23 instead it's a website which can also
- 00:54:25 access some device features
- 00:54:27 browsers are evolving and give you more
- 00:54:30 and more access to these features
- 00:54:32 but you can't control which browser your
- 00:54:35 users are going to use
- 00:54:36 so maybe their users are using a browser
- 00:54:39 which does not support that feature
- 00:54:41 so this is a nice way of creating a app
- 00:54:45 for cases where you can fall back to a
- 00:54:48 well
- 00:54:48 less capable version but if you're
- 00:54:50 building an app that needs to be able to
- 00:54:52 take
- 00:54:52 pictures well then you might need a
- 00:54:55 mobile app
- 00:54:56 now the third alternative gives you a
- 00:54:58 native mobile app just as flutter does
- 00:55:00 but it uses a different approach you can
- 00:55:03 use solutions like ionic cordova
- 00:55:05 you might not have heard of these but
- 00:55:06 what they do is they give you a real
- 00:55:09 native app but they give you a wrapper
- 00:55:11 which just runs a browser in that app
- 00:55:12 you could say
- 00:55:13 and therefore you create a web app which
- 00:55:16 then runs in the browser which is
- 00:55:18 guaranteed to be able to use certain
- 00:55:20 features
- 00:55:21 ionic cordova gives you access to these
- 00:55:23 features but you still have a website
- 00:55:25 the cool thing is if you're a web
- 00:55:27 developer this is pretty easy to use and
- 00:55:29 pretty easy to create
- 00:55:31 awesome apps with it that look really
- 00:55:33 great but of course the performance is a
- 00:55:35 bit worse
- 00:55:36 than when building real native apps or
- 00:55:38 when having real native apps in the end
- 00:55:40 as you do with flutter because here
- 00:55:43 obviously everything runs in a browser
- 00:55:44 still
- 00:55:45 so you have this extra layer with
- 00:55:47 flutter you get real native apps because
- 00:55:50 everything is compiled to native code
- 00:55:52 and therefore performance is better so
- 00:55:54 flutter
- 00:55:55 is not the worst solution and flutter is
- 00:55:57 definitely a cool tool to learn
- 00:55:59 which should make the development of
- 00:56:01 native mobile apps
- 00:56:02 way easier than it was in the past
- 00:56:09 you might have seen it in that first
- 00:56:11 little app we spun up a few lectures ago
- 00:56:14 flutter uses the material design now
- 00:56:16 this looks something like this you might
- 00:56:18 have seen that
- 00:56:18 in different google apps material design
- 00:56:21 is a design system developed by google
- 00:56:24 it's not google's style only though
- 00:56:27 instead
- 00:56:28 it's highly customizable and in this
- 00:56:30 course you will see that you can set
- 00:56:32 different colors that you can change the
- 00:56:33 look of widgets
- 00:56:34 you can do a lot with it it's important
- 00:56:37 to understand
- 00:56:38 that flutter embraces that material
- 00:56:40 design though
- 00:56:41 but you can tweak and adjust basically
- 00:56:43 everything you can add or remove drop
- 00:56:45 shadows you can change colors
- 00:56:47 so you can make it your design you're
- 00:56:49 not creating a google app here that's
- 00:56:51 really important to understand
- 00:56:53 but it's also important to understand
- 00:56:55 that you're going to use that material
- 00:56:56 design
- 00:56:57 for both android and ios though there
- 00:57:00 are some
- 00:57:00 ios specific widgets which really have
- 00:57:03 that ios
- 00:57:04 look i'll have a whole module about that
- 00:57:06 four cases where you need it
- 00:57:08 but in general be prepared to use that
- 00:57:10 material design
- 00:57:11 and adjust it to your requirements well
- 00:57:13 you will see how it works
- 00:57:15 in that course obviously so material
- 00:57:17 design
- 00:57:18 is built into flutter and embraced by
- 00:57:21 flutter you'll see the term
- 00:57:23 material a lot because a whole flutter
- 00:57:25 app is in general
- 00:57:26 a material app where you then add
- 00:57:28 various widgets
- 00:57:34 with all of that out of the way it's
- 00:57:36 time to dive into flutter and learn
- 00:57:38 about its core features we'll do this
- 00:57:40 soon but
- 00:57:41 here's one important thing flutter is a
- 00:57:43 moving target
- 00:57:44 it's actively under development it's
- 00:57:46 still evolving and evolving quickly
- 00:57:49 it's stable now and marked as ready for
- 00:57:51 production
- 00:57:52 by the vladimir team so we shouldn't
- 00:57:54 expect huge braking changes
- 00:57:56 but new features could be added tiny
- 00:57:58 things could change
- 00:58:00 i'll do my best to keep you updated but
- 00:58:02 it's a good idea for you to also
- 00:58:04 regularly check the official docs stay
- 00:58:06 updated follow these steps i will
- 00:58:09 highlight at the end of the course
- 00:58:10 in the roundup it's also important to
- 00:58:13 understand that since flutter is
- 00:58:15 relatively new
- 00:58:16 we have already a decent set of
- 00:58:18 third-party packages
- 00:58:20 adding certain functionalities and
- 00:58:21 making certain things easier
- 00:58:23 but we'll probably see more third-party
- 00:58:25 packages being added
- 00:58:27 to the ecosystem as this well becomes
- 00:58:30 older
- 00:58:31 additionally we have some best practices
- 00:58:33 and patterns and i do my best to follow
- 00:58:35 them and show them in this course
- 00:58:37 but obviously some new patterns might
- 00:58:39 emerge in the future
- 00:58:41 so here too it's a good idea to stay up
- 00:58:43 to date and be prepared to switch to
- 00:58:45 other
- 00:58:46 patterns when they become more stable or
- 00:58:50 if something becomes a best practice
- 00:58:52 last but not least
- 00:58:54 there will be bugs there will be bugs in
- 00:58:56 this course and we will fix them
- 00:58:57 together we will find workarounds
- 00:58:59 and you will see that you can achieve
- 00:59:01 pretty much everything with flutter
- 00:59:03 sometimes you need to be creative but
- 00:59:05 that's not necessarily a problem you
- 00:59:07 still save so much time
- 00:59:08 because you don't have to learn two
- 00:59:09 different languages and these languages
- 00:59:11 would have some bugs too
- 00:59:13 but be prepared to meet some bugs and
- 00:59:16 to fix some things which you might have
- 00:59:19 expected to work out of the box
- 00:59:21 which just don't yet this might always
- 00:59:23 change when you're viewing this at a
- 00:59:25 later point of time
- 00:59:26 but it's important to understand that
- 00:59:28 flutter is under
- 00:59:29 active development which and that's
- 00:59:31 really important is a good thing
- 00:59:32 it means new features improved stability
- 00:59:35 and
- 00:59:36 a growing echo system
- 00:59:43 with all that out of the way let's wrap
- 00:59:45 up this first module
- 00:59:46 and let me show you what's inside this
- 00:59:48 course we're pretty much done with
- 00:59:50 getting started
- 00:59:51 in the next course module we'll have a
- 00:59:52 look at what these widgets are
- 00:59:54 how we create our own widgets how they
- 00:59:56 work together
- 00:59:57 and in general we'll dive into all the
- 01:00:00 basics
- 01:00:00 of the flutter framework and the dart
- 01:00:02 language you'll learn this
- 01:00:04 along the way now thereafter you will
- 01:00:06 learn how to debug your flutter app
- 01:00:08 how to run it on different devices on
- 01:00:10 emulators on
- 01:00:11 iphones on android devices how to do all
- 01:00:14 that because
- 01:00:15 obviously testing and debugging your app
- 01:00:17 is a super important part
- 01:00:18 of the whole development cycle now
- 01:00:21 thereafter you will learn how to render
- 01:00:23 lists of content
- 01:00:24 and how to do that in a high performance
- 01:00:27 way and you'll learn
- 01:00:28 how to render conditional content so how
- 01:00:30 to render something
- 01:00:32 if some condition is met that is a
- 01:00:34 common scenario
- 01:00:35 and you will learn how it works in this
- 01:00:37 module once we're done with that it's
- 01:00:39 time to dive into navigation
- 01:00:41 a flutter app or any app typically has
- 01:00:43 more than one page and you'll learn how
- 01:00:45 to navigate between these pages
- 01:00:47 how to pass data back and forth how to
- 01:00:49 add tabs
- 01:00:50 how to add a site drawer all that fun
- 01:00:52 stuff
- 01:00:54 once done with that we'll dive into user
- 01:00:56 input and how to handle it how to
- 01:00:58 present a text field and react to
- 01:01:00 keystrokes so when the user types
- 01:01:02 something
- 01:01:04 as a next step i'll dive deeper into
- 01:01:06 widgets i'll explain where you find all
- 01:01:08 available widgets
- 01:01:09 how to layout pages and in general dive
- 01:01:12 a bit deeper into this whole concept
- 01:01:14 and into everything you need to know
- 01:01:16 about them it's then
- 01:01:18 time to go back to user input but in a
- 01:01:20 more advanced way
- 01:01:21 you'll learn how to add forums which is
- 01:01:23 just a group of inputs basically
- 01:01:26 and how to validate user input is that
- 01:01:28 email address really a email address
- 01:01:30 we'll find out in this module thereafter
- 01:01:33 we'll have a look at some improvements
- 01:01:35 for the app we're building because as i
- 01:01:37 mentioned already we'll build an entire
- 01:01:39 app throughout this course
- 01:01:40 and here we'll reflect on it for the
- 01:01:43 first time and improve some things
- 01:01:45 and then we'll dive into new features
- 01:01:47 and specifically into models and state
- 01:01:49 management
- 01:01:50 this sounds abstract but by the point we
- 01:01:52 reach this you'll know what i mean
- 01:01:54 and this essentially means how do we
- 01:01:56 work with the data in our app
- 01:01:58 we'll learn it in this module thereafter
- 01:02:02 we'll not just work with data on the
- 01:02:04 device we're running the app but also
- 01:02:06 you will learn how to send it to servers
- 01:02:09 so that you can store it in databases
- 01:02:10 there or how you can fetch data so how
- 01:02:12 you can communicate
- 01:02:14 with some backends across the web and
- 01:02:16 then it's time for
- 01:02:18 some user authentication because most
- 01:02:20 apps require authenticated users you
- 01:02:22 will learn how to edit
- 01:02:23 how to add logout how to manage the user
- 01:02:26 authentication status
- 01:02:27 in this module it's then time for some
- 01:02:30 native device features
- 01:02:32 how can we get the user location how can
- 01:02:34 we render maps
- 01:02:36 how can we access the device camera take
- 01:02:38 pictures or get an image from the
- 01:02:40 gallery
- 01:02:40 all questions answered in these two
- 01:02:42 modules
- 01:02:44 we're nearing the end then but not
- 01:02:46 before talking about animations
- 01:02:48 how can you fade and slide elements how
- 01:02:50 can you set up your own route transition
- 01:02:53 and not use the default one that will be
- 01:02:55 covered in this module
- 01:02:57 thereafter we'll do some polishing and
- 01:02:59 bug fixing because the app is almost
- 01:03:01 done
- 01:03:02 and then we'll dive into platform
- 01:03:05 specific code
- 01:03:06 how can you determine on which platform
- 01:03:08 you're running is it ios is it
- 01:03:10 android you'll learn it in this module
- 01:03:12 once done with that
- 01:03:14 we'll learn how to add native code so
- 01:03:16 how you can
- 01:03:18 implement a certain feature which might
- 01:03:20 not be available in flutter and for
- 01:03:21 which you also don't find a third party
- 01:03:23 package
- 01:03:24 how you can implement that by writing
- 01:03:26 your native code
- 01:03:27 on your own so writing java or swift or
- 01:03:30 objective c code on your own and then
- 01:03:33 connecting that to flutter
- 01:03:34 you'll probably not need that that often
- 01:03:37 but it's useful to have that feature
- 01:03:39 and it's good to learn about it i guess
- 01:03:42 and then
- 01:03:42 we'll publish the app we're done you
- 01:03:44 will learn how to build it for
- 01:03:45 production
- 01:03:46 and how to ship it to the app stores
- 01:03:49 you'll be
- 01:03:49 a real flutter developer thereafter lots
- 01:03:52 of content to cover
- 01:03:54 let's dive in
- 01:03:59 and to dive in let me explain how you
- 01:04:02 get the most out of the course
- 01:04:03 because that is really important to me
- 01:04:05 obviously watch the videos but do it at
- 01:04:07 your speed
- 01:04:08 pause the videos if i'm going too fast
- 01:04:10 go back to a certain concept which isn't
- 01:04:12 clear
- 01:04:13 use the udemy playback controls to speed
- 01:04:15 me up or slow me down
- 01:04:17 because i try to find the right balance
- 01:04:20 i don't want to bore you i don't want to
- 01:04:22 do a five minute pause after every
- 01:04:24 sentence but obviously i don't want to
- 01:04:26 rush through it
- 01:04:27 so adjust my speed to your needs
- 01:04:30 and make sure that you therefore get the
- 01:04:32 most out of this
- 01:04:33 also code along do the exercises this is
- 01:04:37 really how you learn the most
- 01:04:38 because watching the videos is great
- 01:04:41 practicing that
- 01:04:42 writing code on your own that is very
- 01:04:44 useful
- 01:04:46 so this is a good addition to watching
- 01:04:48 the videos
- 01:04:50 and i do also provide a lot of resources
- 01:04:53 attached to the last lecture of each
- 01:04:55 module you will find my source code
- 01:04:57 and also further links now the source
- 01:04:59 code is not
- 01:05:00 a project you can run already but it is
- 01:05:03 all the dart and flutter code we wrote
- 01:05:05 all the packages we added so that you
- 01:05:07 can compare it to yours
- 01:05:09 or replace yours with it temporarily to
- 01:05:13 find issues fix issues because most of
- 01:05:15 the issues
- 01:05:16 can be fixed by simply comparing code
- 01:05:18 that's why i'm providing it
- 01:05:20 now if there is something you absolutely
- 01:05:22 can't fix or if there is something you
- 01:05:24 didn't understand logically
- 01:05:25 you can post questions in the q a
- 01:05:27 section i'll do my best to answer course
- 01:05:30 related questions
- 01:05:31 as fast as i can but i also want to
- 01:05:34 encourage you
- 01:05:35 to help your fellow students answer
- 01:05:37 questions
- 01:05:38 not because i'm lazy but because this
- 01:05:41 challenges you
- 01:05:42 to think about the concept you thought
- 01:05:44 you understood
- 01:05:46 so definitely do that help our students
- 01:05:49 answer questions
- 01:05:50 and don't be afraid of giving a wrong
- 01:05:52 answer what could happen you get
- 01:05:53 corrected and then you learn more
- 01:05:55 so help other students this is a great
- 01:05:58 way of learning more
- 01:05:59 and using the things you learned and
- 01:06:01 practicing them so great learnings
- 01:06:03 are guaranteed with this approach and
- 01:06:05 now with that
- 01:06:06 time to leave this module and to dive
- 01:06:09 into widgets
- 01:06:10 flutter basics and write a lot of code
- 01:06:16 welcome to this module where we will
- 01:06:19 finally dive into flutter
- 01:06:21 and dart and how we use flutter to build
- 01:06:23 amazing
- 01:06:24 mobile apps in this module i'll walk you
- 01:06:28 through all the core basics you have to
- 01:06:30 know about flutter
- 01:06:31 and that mainly is about widgets widgets
- 01:06:34 as you will learn are the core building
- 01:06:37 blocks you use to build your uis your
- 01:06:40 user interfaces for your flutter apps
- 01:06:42 and you will learn how to use built-in
- 01:06:44 widgets how these are organized
- 01:06:46 and also how you create your own widgets
- 01:06:49 and you'll of course not just learn that
- 01:06:51 in theory but we'll use them to start
- 01:06:53 building our course project already
- 01:06:55 and whilst we're on that we'll also dive
- 01:06:57 into some other basics
- 01:06:59 also regarding the dart language so the
- 01:07:02 programming language used by flutter
- 01:07:04 i won't bore you with a dart only
- 01:07:07 introduction
- 01:07:08 i believe it's much better to learn it
- 01:07:10 whilst you are also learning flutter
- 01:07:13 so you will learn everything you need to
- 01:07:14 know about dart whilst you also learn
- 01:07:16 flutter and how to build apps with it
- 01:07:19 so with that let's dive right in let's
- 01:07:21 create a new flutter app
- 01:07:23 our course project and let's start
- 01:07:26 working on it
- 01:07:31 to create a new flutter app i will again
- 01:07:33 use the flatter command
- 01:07:35 and that command of course is still
- 01:07:37 available since i installed the flutter
- 01:07:40 sdk
- 01:07:40 we did that together in the first course
- 01:07:43 module so make sure to definitely go
- 01:07:45 through that
- 01:07:47 with that installed you can run flatter
- 01:07:49 however not just flutter but the create
- 01:07:52 command from that flatter sdk
- 01:07:54 and then simply pick any project name
- 01:07:56 you want
- 01:07:57 like flutter course just one important
- 01:08:01 note
- 01:08:02 don't use a dash here or anything like
- 01:08:04 that your name
- 01:08:05 should be one word or if you got
- 01:08:07 multiple words separate them with an
- 01:08:09 underscore
- 01:08:10 now with that hit enter and it will
- 01:08:12 create a new folder
- 01:08:14 in that destination where you're running
- 01:08:16 this command so make sure you're running
- 01:08:18 it in the right destination
- 01:08:20 and it will populate this folder with a
- 01:08:22 lot of files that make
- 01:08:24 up your android and ios project written
- 01:08:27 in flutter of course
- 01:08:28 so let's wait for this to finish before
- 01:08:31 we then
- 01:08:31 open it with an ide or editor and work
- 01:08:35 on the code
- 01:08:36 the creation of the project finished and
- 01:08:39 now you see the commands you can run
- 01:08:42 in the log it prints here however i will
- 01:08:45 not
- 01:08:45 run them right now instead i want to
- 01:08:47 open that newly created project
- 01:08:49 and that created folder therefore with
- 01:08:52 an ide
- 01:08:53 here i opened the project with visual
- 01:08:55 studio code
- 01:08:56 a free ide you can use which i also
- 01:08:59 showed you in the first course module
- 01:09:01 you can of course all use android studio
- 01:09:04 as an alternative
- 01:09:05 just make sure that in both ides you got
- 01:09:08 all the flutter plugins or extensions
- 01:09:10 added
- 01:09:10 to get the best flutter development
- 01:09:12 experience now in that ide
- 01:09:14 i also opened the integrated terminal
- 01:09:17 which you can open with
- 01:09:19 view integrated terminal or that
- 01:09:21 shortcut here
- 01:09:22 and in there i can now run the flutter
- 01:09:25 run command
- 01:09:26 since this is already navigated into the
- 01:09:27 project folder
- 01:09:29 however there also is another way of
- 01:09:31 running this but
- 01:09:32 in order to run it we need a virtual
- 01:09:35 device we need an
- 01:09:36 emulated device or a real device but i
- 01:09:38 will go with an emulator so let me
- 01:09:40 quickly start one
- 01:09:43 now to bring that emulator up i'll use
- 01:09:45 android studio however not to write code
- 01:09:47 but to go to the tools
- 01:09:48 the avd manager there there we can
- 01:09:51 manage our virtual devices
- 01:09:53 you see i already got a couple of
- 01:09:54 devices you can always create a new one
- 01:09:57 with create new virtual device on the
- 01:09:58 bottom left
- 01:10:00 click through all these settings choose
- 01:10:02 an image you might need to download one
- 01:10:04 make sure to not use the latest one but
- 01:10:06 use the latest
- 01:10:07 stable one instead and then simply
- 01:10:10 create a device by going through that
- 01:10:11 wizard
- 01:10:12 once you got a device created you can
- 01:10:14 select it here and started with the
- 01:10:16 play button on the right and that will
- 01:10:18 be
- 01:10:19 the only thing i do with android studio
- 01:10:21 here
- 01:10:22 now i got that virtual device up and
- 01:10:24 running and now back in visual studio
- 01:10:26 code
- 01:10:26 i mentioned that there is another way of
- 01:10:28 starting our app
- 01:10:30 and that is to go to debug and then you
- 01:10:32 can select start
- 01:10:33 debugging or use the shortcut or start
- 01:10:36 without
- 01:10:36 debugging or use that shortcut this will
- 01:10:39 also launch the flutter app
- 01:10:40 on the connected virtual or real device
- 01:10:43 and you
- 01:10:44 can choose if you want to go into
- 01:10:45 debugging mode something i will cover in
- 01:10:47 a separate module
- 01:10:48 or for now simply well start the app you
- 01:10:51 might be prompted to select an
- 01:10:52 environment
- 01:10:53 and you should have the option of dart
- 01:10:55 and flutter if you installed the
- 01:10:56 extensions for these tools
- 01:10:58 so select dart and flutter and now this
- 01:11:00 enters the debugging view
- 01:11:02 you can always go back with view
- 01:11:04 explorer or that shortcut to go back
- 01:11:06 into that file explorer
- 01:11:08 and now it will build your flutter
- 01:11:10 application and ship it
- 01:11:12 to that virtual device so let's wait for
- 01:11:15 this to finish
- 01:11:15 on the first startup this can take a
- 01:11:17 while and by the way you get this
- 01:11:19 control panel here at the top
- 01:11:20 where you can always restart it or quit
- 01:11:23 it or
- 01:11:24 pause it and later again we will learn
- 01:11:26 how to use that
- 01:11:27 debugging tool for now let's wait for it
- 01:11:29 to start
- 01:11:31 and here it is so this is the starting
- 01:11:34 application
- 01:11:35 we are starting with and this is the
- 01:11:37 application will
- 01:11:38 not work with we'll write one from
- 01:11:40 scratch indeed so let's do that
- 01:11:42 in the next lecture and the lectures
- 01:11:44 thereafter
- 01:11:49 so we got our flutter app up and running
- 01:11:52 and keep that process running here for
- 01:11:53 now
- 01:11:55 go to the main.dart file in the lib
- 01:11:57 folder and delete
- 01:11:58 everything in there because i want to
- 01:12:00 start with you from scratch
- 01:12:01 to really teach you how this works and
- 01:12:04 how such a flutter app starts
- 01:12:06 now before we start writing code in
- 01:12:07 there let me quickly walk you through
- 01:12:09 the other folders and files we got here
- 01:12:12 the idea folder is a folder for android
- 01:12:14 studio with some basic config
- 01:12:16 don't delete it but you also don't need
- 01:12:18 to work in that
- 01:12:20 no matter if you're using visual studio
- 01:12:21 code or android studio
- 01:12:23 the android and the ios folders are
- 01:12:25 important because they hold
- 01:12:27 the native code and an important part of
- 01:12:30 the app building process
- 01:12:31 which you need for well building an app
- 01:12:34 for these platforms
- 01:12:35 you rarely work in these folders though
- 01:12:38 from time to time you have to
- 01:12:40 and i will show you when that is but
- 01:12:42 these are required
- 01:12:43 since they hold source code which is
- 01:12:45 used by that
- 01:12:46 build process together with your flutter
- 01:12:49 code to
- 01:12:50 build these native apps the build folder
- 01:12:53 is a folder you can ignore for now
- 01:12:55 and there you find your build source
- 01:12:57 code in the end this is required by the
- 01:12:59 build process
- 01:13:00 the lib folder is however where you
- 01:13:02 write your
- 01:13:03 entire flutter app so this is the folder
- 01:13:06 we will work in
- 01:13:07 this is the folder where we write our
- 01:13:09 dart and flutter code
- 01:13:11 the test folder would allow you to write
- 01:13:14 automated tests but this is not
- 01:13:15 something i'll focus on right now and
- 01:13:18 the other files here
- 01:13:19 are basically configuration files for
- 01:13:22 git in case you're using this it's a
- 01:13:24 version control system
- 01:13:26 then a couple of configurations for the
- 01:13:29 sdk for the flutter sdk you don't need
- 01:13:31 to change anything there
- 01:13:33 the pubspec.yaml file configures your
- 01:13:35 overall project and its dependencies
- 01:13:37 though
- 01:13:38 and this is an important file there we
- 01:13:40 will later add third-party packages
- 01:13:42 we're using
- 01:13:43 like for example when we add the camera
- 01:13:46 that we can use the device camera
- 01:13:48 and we will also revisit this from time
- 01:13:50 to time to change certain configurations
- 01:13:52 like for example add static assets for
- 01:13:55 now
- 01:13:56 leave the file as it is and let's go
- 01:13:58 back to the main.dart file
- 01:14:00 and in here i now want to write some
- 01:14:02 basic code to start our application
- 01:14:09 the main.dart file is a very important
- 01:14:11 file and you should not rename
- 01:14:14 it because flutter when building your
- 01:14:16 project
- 01:14:17 will look for that main.dart file and in
- 01:14:20 that file it will look for a special
- 01:14:22 function to execute to essentially start
- 01:14:25 your app
- 01:14:26 on the device so you can think of this
- 01:14:28 as this entire dart code will be
- 01:14:31 compiled and bundled with the android or
- 01:14:34 ios
- 01:14:34 code so it will be bundled into one
- 01:14:36 application which is shipped to your
- 01:14:38 native device
- 01:14:39 and on this device in this app then the
- 01:14:42 main.dart file or
- 01:14:44 one specific function in there will be
- 01:14:46 executed first
- 01:14:47 and that function which it's looking for
- 01:14:49 in the main.dart file
- 01:14:51 is also called main now a function just
- 01:14:54 in case you're
- 01:14:54 relatively new to programming is
- 01:14:56 essentially a
- 01:14:58 block of code you define which doesn't
- 01:15:00 execute immediately
- 01:15:01 but which needs to be called to be
- 01:15:03 executed
- 01:15:04 a function in flutter is created by
- 01:15:08 typing the name
- 01:15:09 like main and this specific function
- 01:15:12 which flutter is looking for at app
- 01:15:15 startup
- 01:15:16 has to be named main in general you can
- 01:15:19 name
- 01:15:19 functions how you want but this one has
- 01:15:21 to be named main since flutter is
- 01:15:23 looking for
- 01:15:24 it so you type the name of that function
- 01:15:26 and then parentheses
- 01:15:28 and here you could specify any arguments
- 01:15:31 parameters this function would receive
- 01:15:34 so
- 01:15:34 data that function can use inside of its
- 01:15:36 body
- 01:15:37 the main function however doesn't
- 01:15:39 receive any
- 01:15:40 now the function body is the code which
- 01:15:42 should be executed
- 01:15:43 and you define it by adding curly braces
- 01:15:46 opening and closing
- 01:15:48 the code in here will be executed
- 01:15:49 whenever the main function is called
- 01:15:52 and if you were to call it you would
- 01:15:54 call it like this
- 01:15:55 simply by typing main this would execute
- 01:15:58 the main function here
- 01:16:00 however for this special function we
- 01:16:02 won't call it
- 01:16:03 flutter will do that for us
- 01:16:05 automatically which is why you have to
- 01:16:07 name it main
- 01:16:07 and why it should be in the main.dart
- 01:16:09 file now in here
- 01:16:11 you basically start your app which means
- 01:16:14 you start rendering the user interface
- 01:16:17 all the heavy lifting
- 01:16:18 you hook it into the operating system
- 01:16:20 and so on that is done with the android
- 01:16:22 and ios files you could say
- 01:16:24 but to bring something onto the screen
- 01:16:26 you have to
- 01:16:28 do something in that main function
- 01:16:31 and that something is that you need to
- 01:16:34 attach
- 01:16:34 a widget to the screen now what is a
- 01:16:37 widget
- 01:16:41 flutter is all about widgets widgets
- 01:16:45 are basically building blocks user
- 01:16:47 interface components you could say
- 01:16:49 with which you create your well user
- 01:16:51 interface so what the user
- 01:16:53 sees on the screen if you have a flutter
- 01:16:55 app so a mobile app running on a mobile
- 01:16:57 device
- 01:16:58 it typically consists of multiple
- 01:17:00 widgets like the app bar the navigation
- 01:17:02 bar at the top
- 01:17:03 maybe a header image and maybe a list
- 01:17:05 with a couple of list items
- 01:17:07 all these things here are separate
- 01:17:09 widgets and they often contain other
- 01:17:11 widgets like the list here
- 01:17:13 it contains the list items as child
- 01:17:15 widgets
- 01:17:17 the page itself is even a widget the
- 01:17:19 scaffold widget which we will also
- 01:17:21 create on our own throughout this course
- 01:17:23 and even the entire app is wrapped in
- 01:17:25 one root
- 01:17:26 widget so widgets are really just these
- 01:17:29 user interface components
- 01:17:30 but they're not just about the visuals
- 01:17:33 they all contain
- 01:17:34 logic for example a button widget would
- 01:17:36 not just display the button
- 01:17:38 but also you would define what should
- 01:17:40 happen when that button is tapped
- 01:17:43 so that is how you think about flutter
- 01:17:45 you build flutter apps
- 01:17:47 not by doing all the heavy lifting of
- 01:17:50 hooking it into the operating system but
- 01:17:52 by creating user interfaces
- 01:17:55 and the logic that belongs to that user
- 01:17:57 interface
- 01:17:58 things like selecting items uploading
- 01:18:01 things to a server
- 01:18:03 fetching data from a server and
- 01:18:04 rendering it to the screen
- 01:18:06 that is what you do with these widgets
- 01:18:09 and therefore
- 01:18:10 you can think of your flutter app as a
- 01:18:12 tree of these widgets
- 01:18:14 you have one root widget as i just said
- 01:18:16 to wrap your entire app
- 01:18:18 and then you might have widgets for the
- 01:18:19 different pages of your app between
- 01:18:22 which you can navigate around
- 01:18:23 and then you have nested sub subwidgets
- 01:18:25 for list items
- 01:18:27 for user input forms things like that
- 01:18:30 so you really build up such a tree of
- 01:18:32 widgets and you do
- 01:18:34 all of that in code so with dart the
- 01:18:37 programming language
- 01:18:38 now that's the theory not super clear
- 01:18:40 right now i guess
- 01:18:41 so let's see how that works and how we
- 01:18:43 create such a widget
- 01:18:48 right now our flood wrap isn't doing
- 01:18:50 much we have that main function and it
- 01:18:53 will get called for us but we don't know
- 01:18:55 what to do in that main function
- 01:18:57 now i just mentioned that the entire
- 01:18:59 flutter app is built up of widgets
- 01:19:01 so maybe we should start using such a
- 01:19:04 widget
- 01:19:05 so for that we actually create our own
- 01:19:07 root widget this is how you typically
- 01:19:09 start
- 01:19:10 and for that we will use another dart
- 01:19:12 feature classes
- 01:19:14 with the class keyword classes are a
- 01:19:16 concept you might know from other
- 01:19:18 programming languages too
- 01:19:20 dart is an object-oriented programming
- 01:19:22 language which means
- 01:19:24 everything is an object and an object is
- 01:19:26 simply just a data structure
- 01:19:28 classes allow you to create blueprints
- 01:19:31 for new objects
- 01:19:32 so that you can say what should be
- 01:19:34 inside such an object
- 01:19:36 which properties so which data fields
- 01:19:39 should it have what can you do with it
- 01:19:41 this all goes into such a blueprint and
- 01:19:43 with flutter
- 01:19:44 you will work with a lot of classes
- 01:19:46 which ship with the flutter framework
- 01:19:48 but you also create your own
- 01:19:50 ones and if you create your own ones you
- 01:19:52 do that with the class keyword
- 01:19:53 and then you assign a name to the class
- 01:19:56 now class names typically start with a
- 01:19:58 capital character
- 01:19:59 and then you simply well type the name
- 01:20:01 like for example my app
- 01:20:03 at the conventionist you only use one
- 01:20:05 word but if it actually consists of
- 01:20:08 multiple words
- 01:20:09 you capitalize each word in there so
- 01:20:12 my app would be written like this not
- 01:20:14 with a dash
- 01:20:15 not with an underscore now that is a
- 01:20:18 class and now you can add features to it
- 01:20:21 features are two kinds of things you can
- 01:20:24 add
- 01:20:25 functions to classes they will then be
- 01:20:27 called
- 01:20:28 methods and you can also add variables
- 01:20:31 to functions
- 01:20:32 now i haven't covered variables yet but
- 01:20:34 you probably know it from other
- 01:20:36 programming languages
- 01:20:37 variables are simply little data
- 01:20:39 structures
- 01:20:40 like for example a name if you have
- 01:20:43 something like this
- 01:20:44 well name would be a variable holding
- 01:20:47 max as a value
- 01:20:49 and if you add such a variable to a
- 01:20:51 class it's named
- 01:20:52 a property but that's some theory which
- 01:20:54 will become clearer once we continue
- 01:20:57 there is one other more important
- 01:20:58 feature we need to cover right now
- 01:21:00 we want to create a widget and a widget
- 01:21:03 will be an object which is why we create
- 01:21:05 a class to define how that object should
- 01:21:07 look like
- 01:21:08 however flutter of course doesn't know
- 01:21:11 if a class created by us is something it
- 01:21:14 can use
- 01:21:15 as a widget because as you will learn it
- 01:21:18 needs
- 01:21:18 certain features in a class to be able
- 01:21:21 to use it as a widget
- 01:21:22 so to draw it to the screen and
- 01:21:25 therefore
- 01:21:25 our class has to extend something this
- 01:21:28 is a concept called inheritance
- 01:21:30 and you implement it by adding the
- 01:21:32 extends keyword here
- 01:21:34 this allows you to inherit from a base
- 01:21:37 class
- 01:21:38 so from another class and this means
- 01:21:40 this class
- 01:21:41 will receive all the features of the
- 01:21:43 class it inherits from
- 01:21:45 and it can still use or add its own
- 01:21:48 features
- 01:21:49 and since we then inherit from a class
- 01:21:51 flutter also knows that it can safely
- 01:21:53 use
- 01:21:53 objects based on that class to draw
- 01:21:55 something onto the screen
- 01:21:57 now the thing we extend from therefore
- 01:22:00 has to come from the flutter framework
- 01:22:02 and that is where we implement another
- 01:22:04 feature imports
- 01:22:06 in this file we write our own code but
- 01:22:09 we want to use code
- 01:22:10 which is exposed from the flutter sdk
- 01:22:12 and framework
- 01:22:13 and for that you add an import statement
- 01:22:15 by typing import
- 01:22:17 and then the path to the file you want
- 01:22:20 to import from
- 01:22:21 because start is actually a modular
- 01:22:24 language
- 01:22:24 which means you split your code across
- 01:22:27 multiple files
- 01:22:28 and in this case we're using code which
- 01:22:30 we didn't even write
- 01:22:31 but which is stored in a third-party
- 01:22:33 package in the flatter
- 01:22:35 framework package we import code from
- 01:22:38 such a package
- 01:22:39 by typing package between the quotation
- 01:22:41 marks
- 01:22:42 and then a colon and then the name of
- 01:22:44 the package which is flutter in our case
- 01:22:46 and then flutter actually consists of
- 01:22:48 multiple sub
- 01:22:50 packages or files you could say and you
- 01:22:53 target
- 01:22:53 a file by adding a slash and then the
- 01:22:56 name of the file
- 01:22:57 in our case it will be material.dart
- 01:23:00 this
- 01:23:00 imports this package from the flutter
- 01:23:02 framework and this is available because
- 01:23:04 we have a flatter project here
- 01:23:06 now we can extend a feature which is
- 01:23:08 exposed from that package
- 01:23:10 and that is the so called state less
- 01:23:13 widget there also is another widget
- 01:23:16 the state full widget but we will use
- 01:23:18 the stateless widget for now
- 01:23:21 simply type it like this and this is
- 01:23:23 available because of this import
- 01:23:26 now this class is based on the stateless
- 01:23:29 widget
- 01:23:29 and therefore we can almost use it as a
- 01:23:33 widget
- 01:23:34 to draw it onto the screen one important
- 01:23:37 thing is missing though
- 01:23:38 we'll dive into it in the next lecture
- 01:23:44 so we're extending from stateless widget
- 01:23:47 and therefore
- 01:23:48 i have a valid widget here
- 01:23:51 almost we can already see that there are
- 01:23:54 some red squiggly lines
- 01:23:55 under my app if we hover over my app
- 01:23:58 then you should see this error message
- 01:24:00 that a concrete implementation
- 01:24:02 of stateless widget build is missing now
- 01:24:05 that's not super clear but it's telling
- 01:24:07 us that something is missing in a class
- 01:24:09 something named build well to be precise
- 01:24:12 it's a method named build so let's add
- 01:24:15 it by typing build
- 01:24:16 parentheses and then curly braces
- 01:24:19 this is how you define a function and if
- 01:24:21 a function is inside a class
- 01:24:23 you simply call it method so now we have
- 01:24:26 the build
- 01:24:26 method in this class and now only the
- 01:24:29 build method has red squiggly lines not
- 01:24:31 the my app anymore
- 01:24:32 the build method is required because if
- 01:24:36 we tell flutter
- 01:24:37 to use an object based on this class
- 01:24:40 as a widget it can draw onto the screen
- 01:24:43 it of course
- 01:24:44 needs to rely on this being drawable you
- 01:24:47 could say
- 01:24:48 and flutter will try to draw something
- 01:24:51 by calling
- 01:24:52 the build method on an object where you
- 01:24:55 tell it that it's a widget
- 01:24:56 so if you pass an object to flutter to
- 01:24:58 draw it onto the screen
- 01:25:00 flutter will always call a build method
- 01:25:03 on that object which is why you need to
- 01:25:04 add it to your own widgets
- 01:25:06 now the build method actually takes
- 01:25:08 arguments
- 01:25:09 data which will get passed into it by
- 01:25:12 flutter because flutter
- 01:25:14 will be the one calling the build method
- 01:25:17 the build method takes one argument to
- 01:25:19 be precise the context
- 01:25:22 context is basically an object with some
- 01:25:24 meta information about your
- 01:25:26 app and the position where this widget
- 01:25:29 is drawn in
- 01:25:30 it for example will contain information
- 01:25:31 about the theme through the colors
- 01:25:33 used in our app for now let's simply
- 01:25:35 ignore it and let's add something to the
- 01:25:37 build method
- 01:25:38 because this method needs to return
- 01:25:40 something which you do by adding the
- 01:25:42 return
- 01:25:42 keyword now this is important because
- 01:25:46 flutter will
- 01:25:46 execute the build method and then it
- 01:25:48 needs to know what to draw onto the
- 01:25:50 screen
- 01:25:51 and that something needs to be returned
- 01:25:53 therefore
- 01:25:54 just calling this will not work instead
- 01:25:56 flutter waits for this method to return
- 01:25:58 something
- 01:25:59 so add the return statement and now the
- 01:26:01 question just is
- 01:26:02 what do we return here there is a very
- 01:26:05 important rule
- 01:26:06 a widget always needs to return another
- 01:26:09 widget
- 01:26:10 in the build method until you reach
- 01:26:12 widgets that ship
- 01:26:13 with flutter now we can use a widget
- 01:26:16 that ships with flutter
- 01:26:18 the material app widget this is a
- 01:26:21 special widget which is used to
- 01:26:23 wrap your entire app so this will
- 01:26:26 actually give you
- 01:26:27 abilities to set up the theming for that
- 01:26:30 app
- 01:26:30 it will also add a navigator which
- 01:26:33 allows you to switch between different
- 01:26:34 pages
- 01:26:35 and so on so this is your core root
- 01:26:38 widget which you use
- 01:26:40 in every flutter app you create you
- 01:26:42 return it in your own
- 01:26:44 widget which will be the top most widget
- 01:26:46 therefore and now the material app
- 01:26:48 widget
- 01:26:49 can be configured to do something to
- 01:26:52 really draw something onto the screen
- 01:26:54 because right now we just created our
- 01:26:55 app but there will be nothing to be seen
- 01:26:59 for that we can pass data to material
- 01:27:01 app by the way please notice the
- 01:27:02 parentheses here
- 01:27:04 material app like this without the
- 01:27:06 parentheses is a class
- 01:27:08 imported from the flutter material
- 01:27:10 package
- 01:27:11 with the parentheses we create an object
- 01:27:14 based on the class you could say
- 01:27:16 we construct an object we call the
- 01:27:18 so-called
- 01:27:19 constructor method of a class every
- 01:27:22 class has one even if you don't
- 01:27:23 explicitly define it
- 01:27:26 so we're executing this and therefore
- 01:27:27 what this gives us is a new object
- 01:27:30 based on that material app class you
- 01:27:32 might also see the syntax where you add
- 01:27:34 a new keyword in front of that
- 01:27:36 as of dart version 2 which we use here
- 01:27:38 and which is the future of dart you
- 01:27:39 don't need that anymore
- 01:27:41 now i mentioned that we can pass
- 01:27:42 information to material app
- 01:27:44 let's do that in the next lecture
- 01:27:50 we already covered a lot of ground but
- 01:27:52 we still don't see anything on the
- 01:27:54 screen
- 01:27:55 for that we need to tell material app
- 01:27:57 which is the wrapper for our entire app
- 01:27:59 what to do what to draw onto the screen
- 01:28:02 and for that you can pass arguments to
- 01:28:04 material app
- 01:28:06 our build method expected an argument
- 01:28:08 the constructor of material app does too
- 01:28:10 it expects so-called named arguments
- 01:28:13 which means
- 01:28:14 you first add a name for example home is
- 01:28:17 such an argument
- 01:28:18 then a colon and then the value you want
- 01:28:20 to pass for that argument
- 01:28:22 the alternative are positional arguments
- 01:28:25 something we're using here
- 01:28:26 there we don't assign a name instead the
- 01:28:28 first argument passed to the build
- 01:28:30 method
- 01:28:30 will be treated as context in this case
- 01:28:32 so it will be stored in that
- 01:28:34 parameter the named argument case is
- 01:28:37 something we'll all use throughout the
- 01:28:38 course
- 01:28:39 material app uses it there we target an
- 01:28:41 argument named home
- 01:28:43 and we pass a value for it and home
- 01:28:46 actually requires another widget
- 01:28:49 this will be the widget which is drawn
- 01:28:51 onto the screen
- 01:28:52 when the app loads here
- 01:28:56 you typically use a so-called scaffold
- 01:28:58 widget another widget
- 01:29:00 shipping with the material package here
- 01:29:03 scaffold creates a new
- 01:29:04 page in your app with a nice white
- 01:29:07 background
- 01:29:08 that can also be changed by the way but
- 01:29:10 with a background with the ability to
- 01:29:12 add a app bar
- 01:29:13 and so on and scaffold therefore also
- 01:29:16 needs to be configured by passing data
- 01:29:18 into the constructor
- 01:29:19 because this will create an empty page
- 01:29:22 to pass something to that page
- 01:29:24 we can target specific arguments here
- 01:29:26 which we passed to scaffold
- 01:29:28 one of them is app bar by writing app
- 01:29:32 bar colon you can add a widget which
- 01:29:35 will be rendered as the
- 01:29:36 application bar the toolbar at the top
- 01:29:39 of the screen
- 01:29:41 and here you guessed it we again need a
- 01:29:43 widget
- 01:29:44 you remember everything is a widget
- 01:29:47 so let's add a widget here and
- 01:29:49 thankfully there already is a built in
- 01:29:51 one app
- 01:29:52 bar like this this creates an instance
- 01:29:54 based on the app
- 01:29:55 bar widget and this now again
- 01:29:59 needs configuration what should go
- 01:30:01 inside of that app bar
- 01:30:02 there is a title argument and if you're
- 01:30:05 wondering how
- 01:30:06 do i know that this has a title property
- 01:30:08 you can hover over app bar
- 01:30:10 and you will see some documentation on
- 01:30:13 which arguments it accepts
- 01:30:15 and there you see the title and you also
- 01:30:18 see
- 01:30:18 that this also requires a widget
- 01:30:22 but you can also use another approach
- 01:30:24 you can put your cursor
- 01:30:26 into the argument list here between the
- 01:30:28 parentheses and hit control space
- 01:30:30 and then your ide should give you this
- 01:30:32 auto completion where it offers
- 01:30:34 some well code snippets that can be used
- 01:30:37 here
- 01:30:37 and there you also see if you start
- 01:30:40 typing that there is a title
- 01:30:42 argument you can target and this as you
- 01:30:45 saw when i hovered over app bar
- 01:30:47 requires another widget which is
- 01:30:49 rendered as a title
- 01:30:51 here we'll use the last widget of this
- 01:30:53 chain and that will be
- 01:30:54 the text widget text is a widget
- 01:30:58 which then takes a string as an argument
- 01:31:00 now this is a positional
- 01:31:02 argument we don't define the name
- 01:31:04 instead we just pass a string
- 01:31:06 and then this will be extracted inside
- 01:31:08 of the text widget
- 01:31:09 in the first argument in the argument
- 01:31:11 list so here we pass a string which
- 01:31:13 should be displayed as text
- 01:31:15 like easy list because that will be the
- 01:31:17 name of the app we built
- 01:31:20 now that was a lot of work and it might
- 01:31:22 not all be super clear yet
- 01:31:24 especially knowing that these widgets
- 01:31:26 exist can be confusing
- 01:31:28 but throughout this course you will get
- 01:31:30 a feeling for which widgets exist
- 01:31:31 and of course i will also show you where
- 01:31:33 to find them all
- 01:31:35 for now let's take this as it is and i
- 01:31:38 don't know about you
- 01:31:39 but i think that code can be written in
- 01:31:41 a bit of a more readable way now if you
- 01:31:44 write that code like this and you have
- 01:31:46 that trailing comma here at the end
- 01:31:49 after each parentheses set except for
- 01:31:51 the last one
- 01:31:52 you can use a feature provided by all
- 01:31:55 ides in visual studio code
- 01:31:57 you can find it by going to code
- 01:31:59 preferences keyboard shortcuts
- 01:32:02 and then in there search for format
- 01:32:05 document this is a command
- 01:32:08 which you can rebind or use as you find
- 01:32:10 it here
- 01:32:12 which you can execute in your code to
- 01:32:14 automatically
- 01:32:15 reorganize it and make it more readable
- 01:32:18 now this looks much nicer in my opinion
- 01:32:20 we still wouldn't see anything on the
- 01:32:22 screen though and the reason for
- 01:32:24 that is that we created our widget
- 01:32:27 but we're not mounting it to the screen
- 01:32:30 now let's do that last step by going
- 01:32:32 back to the main function here
- 01:32:34 we're not executing any code in there
- 01:32:36 time to change that
- 01:32:38 we need to run a special function here a
- 01:32:40 function provided by the material
- 01:32:42 package we import
- 01:32:44 it's a function called run app my ide
- 01:32:46 helps me and automatically suggests it
- 01:32:49 and run app takes an argument and that
- 01:32:51 argument
- 01:32:52 has to be a widget so
- 01:32:55 let's create a widget here and we will
- 01:32:58 use our my app widget which then wraps
- 01:33:00 material app scaffold and so on
- 01:33:03 so use your class name here and then add
- 01:33:06 parentheses
- 01:33:07 to construct an object based on that
- 01:33:10 class
- 01:33:10 because classes are blueprints you
- 01:33:13 create concrete objects based on them
- 01:33:16 by executing the classes just like you
- 01:33:18 execute functions
- 01:33:20 with that save that and now it will try
- 01:33:24 to hot reload that
- 01:33:25 into your running emulator and you
- 01:33:27 should see something like this
- 01:33:28 if it fails for some reason quit this
- 01:33:31 and restart it without debugging
- 01:33:33 if you make fundamental changes like
- 01:33:35 this one it can break
- 01:33:37 most of the time though it should
- 01:33:39 automatically reload if you just save
- 01:33:41 the code
- 01:33:41 and then you should see this and now
- 01:33:44 this is our own app with our
- 01:33:46 configuration
- 01:33:47 you can see the app bar you see the
- 01:33:48 white background which is coming from
- 01:33:50 the scaffold
- 01:33:51 the page which is created and the
- 01:33:53 overall app
- 01:33:54 is wrapped by the material app widget
- 01:33:57 now
- 01:33:57 again don't worry if that is a lot of
- 01:34:00 new information to digest
- 01:34:02 getting started is hearted but we will
- 01:34:04 practice and practice it
- 01:34:05 so that this will become clearer now
- 01:34:08 let's take a step back and before we
- 01:34:10 continue working on that
- 01:34:12 let me walk you through what we did here
- 01:34:14 and
- 01:34:15 actually how we can enhance this code
- 01:34:17 from a dart
- 01:34:18 so from the programming language we're
- 01:34:19 using perspective
- 01:34:25 we created our first very basic flutter
- 01:34:28 app
- 01:34:29 and we do this by calling run app in
- 01:34:31 this important main function
- 01:34:33 in the main dart file where we construct
- 01:34:35 an object
- 01:34:36 based on our own class which essentially
- 01:34:39 calls the build or has the build method
- 01:34:41 it will be called by flutter where we
- 01:34:43 then return our widget tree
- 01:34:46 now we use dart to write all of that so
- 01:34:49 the import statement the function syntax
- 01:34:51 the class this all is dart and
- 01:34:54 dart actually is a typed language which
- 01:34:57 means
- 01:34:58 you should define the types your
- 01:35:02 methods use or your variables store
- 01:35:06 this helps you with development because
- 01:35:08 your ide can use that information
- 01:35:10 and warn you if you try to save a wrong
- 01:35:12 type and
- 01:35:14 it will always be picked up during the
- 01:35:15 build process and also potentially yell
- 01:35:18 at you
- 01:35:19 if you're using something incorrectly
- 01:35:21 now what do i mean with that
- 01:35:23 for example the build method i mentioned
- 01:35:26 that it has to return a widget
- 01:35:28 and we don't see any errors here because
- 01:35:30 dart is actually able to infer
- 01:35:32 the type since we return material app
- 01:35:35 which is a widget
- 01:35:36 dart knows that the build method will
- 01:35:39 eventually return a widget
- 01:35:41 however we can be really clear about
- 01:35:43 this by adding the
- 01:35:44 widget word in front of build now widget
- 01:35:47 is a class however not instantiated
- 01:35:51 but instead just a class name which then
- 01:35:54 acts as a type in dart
- 01:35:56 which means this to be precise is a
- 01:35:58 class defined by the flutter package in
- 01:36:00 the material package
- 01:36:02 and it means that widget is now what we
- 01:36:04 expect to return and build
- 01:36:06 and if for some reason we wouldn't
- 01:36:08 return
- 01:36:09 this year the material app let's say we
- 01:36:12 comment
- 01:36:12 this all out and we instead return a
- 01:36:15 string here
- 01:36:17 then you would see that we get an error
- 01:36:19 and we see the return type string
- 01:36:21 isn't a widget as defined by the method
- 01:36:24 build so we would get a warning
- 01:36:26 and if i save this it wouldn't even
- 01:36:28 recompile because it recognizes that our
- 01:36:31 code is incorrect
- 01:36:33 so adding these types allows us to write
- 01:36:35 cleaner code
- 01:36:36 it allows us to avoid errors
- 01:36:39 now we can't just define a type in front
- 01:36:42 of the build method
- 01:36:43 we can also be very clear about which
- 01:36:45 type this argument will have
- 01:36:47 again it's able to infer this because
- 01:36:50 build actually is a method already
- 01:36:52 defined by stateless widget but then
- 01:36:54 marked as
- 01:36:55 has to be overwritten but we can be very
- 01:36:57 clear about that
- 01:36:58 by adding the type in front of the
- 01:37:00 argument and that's the general theme
- 01:37:02 you add the type in front of your
- 01:37:05 function
- 01:37:06 your variable your parameter to define
- 01:37:09 what this will hold here this is
- 01:37:11 actually of type
- 01:37:12 build context another class provided by
- 01:37:15 the
- 01:37:15 flutter material package so now we're
- 01:37:18 very clear about the context being of
- 01:37:20 type build context
- 01:37:22 and it doesn't change our app but it
- 01:37:24 ensures that we don't make dumb
- 01:37:26 mistakes and it also helps us with the
- 01:37:29 ide because if i now type context
- 01:37:31 and then dot to access one of its
- 01:37:33 methods or properties
- 01:37:35 i get suggestions that belong to the
- 01:37:37 build context type
- 01:37:39 so i'm not getting any suggestions that
- 01:37:41 wouldn't exist anyways
- 01:37:42 we can also be clear about the type the
- 01:37:45 main method returns
- 01:37:46 now you might say it doesn't return
- 01:37:48 anything and you're right
- 01:37:50 and in this case you add a white in
- 01:37:52 front of it to indicate
- 01:37:53 this method doesn't return anything and
- 01:37:55 it shouldn't
- 01:37:56 if we now do add a return statement and
- 01:37:59 return anything but nothing
- 01:38:00 this returns nothing so this would be
- 01:38:02 valid but if we return a string let's
- 01:38:04 say
- 01:38:04 then we again would get an error that
- 01:38:06 the return type string
- 01:38:07 isn't avoid and void just means empty
- 01:38:11 now you don't need to return nothing
- 01:38:12 like this you can't just omit this line
- 01:38:15 and now the code behaves exactly as
- 01:38:17 before as you can tell
- 01:38:18 but it's better code using types is
- 01:38:21 strongly recommended
- 01:38:23 and allows you to write cleaner code
- 01:38:25 it's not all i want to
- 01:38:26 discuss about the dart language though
- 01:38:28 types are a crucial
- 01:38:30 feature and we will use them throughout
- 01:38:31 this course but there are two other
- 01:38:33 things i want to mention right now
- 01:38:35 the first one is the way we write this
- 01:38:37 function if you have a function
- 01:38:39 which only contains one statement like
- 01:38:42 this one does
- 01:38:43 you can absolutely write it like this
- 01:38:45 nothing wrong with it
- 01:38:46 use this style if you like it there is a
- 01:38:48 shortcut though
- 01:38:49 a shorter notation and that's the fat
- 01:38:52 arrow notation
- 01:38:54 you use it by removing the curly braces
- 01:38:57 and then you instead write it all in one
- 01:38:59 line but you separate
- 01:39:01 the name and argument list from the
- 01:39:03 function body
- 01:39:05 by using an arrow an equal sign and then
- 01:39:08 a greater than sign
- 01:39:09 and now this is the equivalent to the
- 01:39:11 function we had before
- 01:39:13 it's only valid if you have exactly one
- 01:39:15 statement but this is also something you
- 01:39:17 will see throughout the course
- 01:39:18 this shorter function notation
- 01:39:21 and last but not least there is
- 01:39:23 something special about the build method
- 01:39:25 which we also have for some other
- 01:39:27 methods throughout this course
- 01:39:28 this is actually a method for which
- 01:39:30 stateless widgets
- 01:39:32 requires us to overwrite it and we can
- 01:39:35 therefore add a special annotation here
- 01:39:37 it's not required as you can tell
- 01:39:40 everything works without it
- 01:39:41 but you can add an annotation by adding
- 01:39:43 a add sign
- 01:39:44 and then here it's the override
- 01:39:46 annotation
- 01:39:48 what this does is it simply tells dart
- 01:39:50 and flutter
- 01:39:51 that we deliberately overwrite a method
- 01:39:54 which is
- 01:39:55 also already the find and stateless
- 01:39:57 widget now it works without that but if
- 01:39:59 we're working in a team of developers
- 01:40:01 this makes it very clear that this is a
- 01:40:03 method that actually overrides a method
- 01:40:05 defined by this widget
- 01:40:07 and that makes our code easier to read
- 01:40:10 with all that
- 01:40:11 if we save the application it will look
- 01:40:14 and feel exactly as it did before
- 01:40:16 but now we got our well cleaner code
- 01:40:20 back to flutter then let's add more to
- 01:40:22 this app
- 01:40:23 because right now you could certainly
- 01:40:24 argue that it's not looking
- 01:40:26 that exciting
- 01:40:32 let's continue working on our app right
- 01:40:34 now we only got
- 01:40:35 that app bar which is nice but not that
- 01:40:38 awesome
- 01:40:39 remember that the scaffold widget was
- 01:40:41 used to create a page
- 01:40:44 and we cannot just add a app bar there
- 01:40:47 we can also add other arguments and
- 01:40:49 let's say again use that control space
- 01:40:51 trick
- 01:40:52 for example a body that is actually
- 01:40:55 what's displayed well
- 01:40:56 on the page itself below the app bar in
- 01:40:59 all that white space here
- 01:41:02 the body you guessed it also expects a
- 01:41:04 widget which you can see if you hover
- 01:41:05 over it
- 01:41:06 here you can see the type you also get a
- 01:41:09 short
- 01:41:10 explanation about how it works and what
- 01:41:12 it does and
- 01:41:13 therefore let's add a widget here now we
- 01:41:15 could again create another widget
- 01:41:18 on our own and then add this here but
- 01:41:20 ultimately you'll always
- 01:41:21 end up with a tree of widgets built into
- 01:41:24 the flutter material package
- 01:41:26 your own widgets which you use a lot
- 01:41:28 will also
- 01:41:29 well be composed of either other which
- 01:41:32 is built by you but finally somewhere at
- 01:41:34 the end of the chain
- 01:41:35 you will be using widgets shipping with
- 01:41:37 flutter because
- 01:41:38 these are actually then translated to
- 01:41:41 native
- 01:41:41 user interface components so that is why
- 01:41:44 you always will end up
- 01:41:45 with flatter built-in widgets somewhere
- 01:41:47 down the road
- 01:41:49 for the body here let's say we want to
- 01:41:51 add
- 01:41:52 a card you know this card look from
- 01:41:56 material design apps well if you don't
- 01:41:58 you'll see it in a second you can add it
- 01:42:00 by using the card
- 01:42:01 widget and as you were probably guessing
- 01:42:05 this is all the shipping with the
- 01:42:06 flutter material package so
- 01:42:08 all is unlocked with this single import
- 01:42:11 the card will give us this highlighted
- 01:42:14 content
- 01:42:15 look with a slight drop shadow and so on
- 01:42:18 and this card again takes a couple of
- 01:42:20 named arguments you can assign
- 01:42:22 like for example most important the
- 01:42:24 child which also is a widget which you
- 01:42:26 can see here
- 01:42:27 on the right so let's add child and that
- 01:42:30 is essentially the content
- 01:42:32 of our card so what we want to have
- 01:42:34 inside of it
- 01:42:35 now let's say we want to have two things
- 01:42:37 in there an image
- 01:42:38 and also a title below the image now to
- 01:42:42 have two elements in there
- 01:42:43 we use a special widget all the shipping
- 01:42:46 with flutter
- 01:42:47 the column widget again takes
- 01:42:50 some arguments which you can see here
- 01:42:53 and it accepts for example
- 01:42:54 children now the difference to child
- 01:42:56 should be clear child is one widget
- 01:42:59 but column actually has multiple widgets
- 01:43:01 which will be positioned above each
- 01:43:03 other
- 01:43:03 so from top to bottom let's hit
- 01:43:06 enter here to enter a new line to make
- 01:43:08 it a bit easier to read
- 01:43:09 now here we can define all the widgets
- 01:43:12 again
- 01:43:13 that should go into the column now if
- 01:43:15 you're wondering what this here is this
- 01:43:17 strange angle brackets widget thing well
- 01:43:20 that's a so-called
- 01:43:21 generic type it's an additional
- 01:43:23 annotation
- 01:43:24 added to the array here to make it
- 01:43:26 really clear that this actually will
- 01:43:28 only hold widgets
- 01:43:30 and i already mentioned it this thing
- 01:43:32 with the square brackets here
- 01:43:33 is called an array it allows us to add a
- 01:43:36 list of data instead of a single data
- 01:43:38 piece
- 01:43:39 column card app or text scaffold
- 01:43:43 these are all just single objects
- 01:43:46 now we can add a list of single objects
- 01:43:49 which will be stored in this
- 01:43:50 children argument that is what we do
- 01:43:53 here
- 01:43:53 and there we can add two items now in
- 01:43:56 that list
- 01:43:57 separated by a comma let's use
- 01:44:00 an image widget unsurprisingly
- 01:44:04 also shipping with flatter material
- 01:44:07 and let's leave it like this for now in
- 01:44:09 the second line
- 01:44:10 let's add a text image again to display
- 01:44:13 some text
- 01:44:14 let's name this one food paradise
- 01:44:18 for now and the image will be an image
- 01:44:20 that holds
- 01:44:21 some food you can find the image
- 01:44:23 attached to this video
- 01:44:25 and let's now create a new folder here
- 01:44:27 in our project
- 01:44:29 which i'll name assets now the name is
- 01:44:31 up to you but assets
- 01:44:33 is a good convention since this will
- 01:44:35 hold static assets
- 01:44:37 off your app now you can find the file
- 01:44:40 attached to this video
- 01:44:42 the food.jpg file which you can just
- 01:44:44 drag and drop into the assets folder
- 01:44:46 this image here now we want to use that
- 01:44:49 image and display it here
- 01:44:51 inside that image widget now
- 01:44:55 to unlock this file we have to inform
- 01:44:58 flutter about it
- 01:44:59 because just dragging it into a folder
- 01:45:01 of this project
- 01:45:02 isn't enough instead we now need to go
- 01:45:05 to the pubspec.yaml file here
- 01:45:08 and there if you scroll down a bit you
- 01:45:10 should find this
- 01:45:11 commented out part where you can add a
- 01:45:14 special assets key which you do by just
- 01:45:16 removing that hash
- 01:45:17 symbol and then you can define assets of
- 01:45:21 your application
- 01:45:22 by removing that hash here and then
- 01:45:24 inventing this
- 01:45:26 leave the dash here that's important it
- 01:45:29 like this
- 01:45:31 and then here you point to the file you
- 01:45:33 want to add
- 01:45:34 in our case it's in the assets folder
- 01:45:37 and there
- 01:45:37 we have the food dot jpeg
- 01:45:41 file with this added and saved you can
- 01:45:44 now
- 01:45:44 use that asset in your project and you
- 01:45:47 see it already updated our project to
- 01:45:49 import
- 01:45:50 this basically so that this will be
- 01:45:52 included in the bundle
- 01:45:53 shipped to the device and now we can go
- 01:45:56 back to the main.dart file and use that
- 01:45:58 image
- 01:45:59 and for that we'll use a special
- 01:46:01 constructor of the image widget
- 01:46:03 we haven't seen this type of constructor
- 01:46:05 yet but there actually
- 01:46:06 is a special constructor you can use by
- 01:46:08 adding a dot after widget
- 01:46:10 but before the parentheses and then
- 01:46:12 asset
- 01:46:13 this is a special type of constructor
- 01:46:15 which will create an image
- 01:46:17 widget that is already configured to
- 01:46:19 load a
- 01:46:20 asset and you now you pass that asset to
- 01:46:23 simply
- 01:46:24 as a string and then the name of the
- 01:46:26 asset
- 01:46:27 the full path to be precise so assets
- 01:46:30 slash food.jpg now if you save this
- 01:46:35 it should hot reload and now if you go
- 01:46:37 back to your app you should see
- 01:46:39 something like this
- 01:46:40 an image and some text below it and this
- 01:46:43 actually is all
- 01:46:44 sitting on a card which takes the entire
- 01:46:46 width and height right now
- 01:46:48 but you can see that slight drop shadow
- 01:46:50 here at the bottom
- 01:46:52 now it's not the final style i want to
- 01:46:54 have but it is
- 01:46:55 a huge advancement and now we got some
- 01:46:58 body here
- 01:46:58 and hopefully you got more practice with
- 01:47:01 building that widget tree
- 01:47:02 you also learned about some other
- 01:47:04 widgets and whilst you already learned
- 01:47:06 about a lot of new widgets
- 01:47:08 these are all core widgets and there are
- 01:47:11 not that many our core widgets left as
- 01:47:13 you will learn
- 01:47:14 for now let's reformat the code with
- 01:47:16 that handy shortcut again
- 01:47:18 and let's see what else we can do
- 01:47:24 are you wondering how i know all these
- 01:47:27 widgets
- 01:47:28 well there is an official flutter
- 01:47:30 documentation which
- 01:47:31 provides an overview on flutter.io
- 01:47:35 you can click on get started or the look
- 01:47:37 and feel of this page might of course
- 01:47:39 change
- 01:47:39 but you should always find some docs
- 01:47:41 area like with the docs link up here
- 01:47:44 and even if this page should change you
- 01:47:47 should find a link to a widget's catalog
- 01:47:49 here or on the left widget catalog
- 01:47:53 if you visit it you get an overview over
- 01:47:55 the widgets
- 01:47:56 flutter ships with organized by
- 01:47:58 categories and the most important
- 01:48:00 category
- 01:48:01 is the basics category but even more
- 01:48:03 important the material components
- 01:48:05 category if you click on that
- 01:48:09 you see an overview over all the core
- 01:48:11 material
- 01:48:12 widgets and i'll come back to what that
- 01:48:14 material thing actually is
- 01:48:17 these are things like the app bar which
- 01:48:19 you saw but these are also then things
- 01:48:21 like the root material app widget
- 01:48:23 or if you scroll down buttons
- 01:48:27 inputs which we'll see dialogs which you
- 01:48:29 can display
- 01:48:30 information displays like tooltips the
- 01:48:33 card
- 01:48:34 here and then layout widgets
- 01:48:38 and if you go back one step and go to
- 01:48:40 the basics widget category
- 01:48:43 here you see things like the column row
- 01:48:46 a container widget which we'll see
- 01:48:47 the text widget the image widget and you
- 01:48:50 can always click on documentation to
- 01:48:52 learn more about it
- 01:48:53 how you can use it for example here's
- 01:48:55 that image asset constructor we used
- 01:48:58 and for some of them not for the image
- 01:49:00 unfortunately but for some of them you
- 01:49:02 also see short example snippets here
- 01:49:04 and even that might look like a lot but
- 01:49:07 this is a great way of getting to know
- 01:49:08 these widgets to navigate around
- 01:49:10 and no worries we will use plenty of
- 01:49:12 them throughout the course
- 01:49:14 so that this will all become much
- 01:49:16 clearer
- 01:49:21 now that you know where to find all
- 01:49:23 these widgets
- 01:49:24 let's continue working on this app thus
- 01:49:27 far we're just displaying our card here
- 01:49:29 it takes the full entire space
- 01:49:31 and that's not too exciting i'd say so
- 01:49:34 time to change this let's give the user
- 01:49:38 the ability to add more and more
- 01:49:41 cards and therefore products as it will
- 01:49:43 be by the end of this course
- 01:49:45 cue this well list of cards which we
- 01:49:47 don't have yet but which we will create
- 01:49:50 now for that we need a list of cards
- 01:49:53 first of all
- 01:49:54 and we can create such a list with the
- 01:49:56 column widget here of course
- 01:49:57 so let's add column like this children
- 01:50:01 and then this array you can't omit this
- 01:50:04 angle bracket widget thing but you can
- 01:50:05 also add it but i will omit it here
- 01:50:08 and also close the square brackets after
- 01:50:11 the card here
- 01:50:14 also add a parentheses here to close
- 01:50:16 that column
- 01:50:17 and then let's reformat the code and now
- 01:50:19 we have a list of cards
- 01:50:21 if we now reload you see the card
- 01:50:23 doesn't go all the way to the bottom
- 01:50:24 but it ends after its content which is
- 01:50:27 the behavior we want
- 01:50:30 now i want to be able to add more
- 01:50:33 cards and let's say for this we add a
- 01:50:35 button
- 01:50:36 we add that button above our other cards
- 01:50:39 here
- 01:50:40 so we could add a button with a special
- 01:50:42 widget
- 01:50:43 the raised button widget for example
- 01:50:46 this adds a raised button which is
- 01:50:48 simply a button with a background color
- 01:50:50 now the raised button needs to be
- 01:50:52 configured so let's see how we can
- 01:50:53 configure it
- 01:50:54 for example and most importantly it has
- 01:50:57 the child
- 01:50:58 argument here there we add a widget
- 01:51:00 which will simply define what's inside
- 01:51:02 of the button
- 01:51:03 this often is text but it could also be
- 01:51:06 an icon for example
- 01:51:07 here i will use the text widget again to
- 01:51:09 add some text and the text i use
- 01:51:11 is add product this will now
- 01:51:15 add such a button however we also need
- 01:51:17 to add one other important
- 01:51:19 argument and we can see that we got some
- 01:51:21 green squiggly lines which tells us that
- 01:51:23 the parameter on pressed is required
- 01:51:26 and we can add it by adding on pressed
- 01:51:28 and this now actually expects a function
- 01:51:31 reference so we can add an empty
- 01:51:33 function here
- 01:51:34 like this and this is a so-called
- 01:51:37 anonymous function
- 01:51:38 it has no name as you can tell it's just
- 01:51:40 the argument list
- 01:51:41 and then the function body both is empty
- 01:51:44 which leads to this looking a bit
- 01:51:45 strange
- 01:51:46 we will populate it with live soon for
- 01:51:48 now this is just an
- 01:51:49 empty function that does nothing that
- 01:51:52 will be executed when we press
- 01:51:54 the button if we now save that and let
- 01:51:56 it hard reload
- 01:51:57 we see that button at the top here and
- 01:52:00 we can click it
- 01:52:01 and we actually see that ripple effect
- 01:52:03 so this is working
- 01:52:04 now this button is sitting at the very
- 01:52:07 edges
- 01:52:08 of our page here we can change this
- 01:52:11 by wrapping it with another widget which
- 01:52:13 you saw in the widget catalog
- 01:52:15 the container widget the container
- 01:52:17 widget
- 01:52:18 takes a child and that child will be our
- 01:52:20 button so let's grab that and
- 01:52:22 add it here reform it and the container
- 01:52:26 widget
- 01:52:27 also allows us to add a so-called margin
- 01:52:30 the margin is simply some space around
- 01:52:33 that container so around the button
- 01:52:35 therefore
- 01:52:36 we added by using another class provided
- 01:52:39 by the flutter material package
- 01:52:41 the edge insets class which has a
- 01:52:44 all constructor called with dot all
- 01:52:48 where you then pass a number a float to
- 01:52:50 be precise which is a number with a
- 01:52:52 decimal place
- 01:52:53 which defines how much space you want to
- 01:52:55 have in all directions
- 01:52:57 for example 10.0 pixels and these will
- 01:53:00 be pixels
- 01:53:00 automatically adjusted to the device
- 01:53:02 pixel density
- 01:53:04 we now saved as you see there is some
- 01:53:06 space around the button
- 01:53:08 obviously the button doesn't do anything
- 01:53:10 so
- 01:53:11 let's ensure that it does something
- 01:53:17 we added this button but if we click it
- 01:53:19 it's not doing anything because our
- 01:53:21 function here is empty
- 01:53:23 now this button should actually add new
- 01:53:27 dummy products for now which we then
- 01:53:29 render below the button
- 01:53:30 by adding more and more cards here this
- 01:53:33 of course
- 01:53:34 for one raises the question how do we
- 01:53:37 add more cards here
- 01:53:39 but obviously another important question
- 01:53:41 is how
- 01:53:42 do we actually create new cards upon a
- 01:53:44 button press
- 01:53:46 well in this function here we want to
- 01:53:49 change
- 01:53:50 some data which actually then is
- 01:53:52 dynamically
- 01:53:53 turned into a list of such card widgets
- 01:53:57 what you typically would do is you
- 01:53:59 manage a normal list of
- 01:54:00 data which you might also fetch from a
- 01:54:02 server and which we will fetch from a
- 01:54:04 server later in this course
- 01:54:06 and then whenever build is called and it
- 01:54:09 will be called by flutter when the app
- 01:54:10 is first loaded
- 01:54:12 or when some of your data changes that's
- 01:54:14 the important part
- 01:54:16 then we want to use the data we're
- 01:54:18 handling in on pressed
- 01:54:20 and recreate a list of cards here which
- 01:54:24 changes therefore
- 01:54:25 with every button press this
- 01:54:28 can't be done in a stateless widget
- 01:54:30 though a stateless widget
- 01:54:31 is a very simple widget that does one
- 01:54:33 important thing
- 01:54:35 it's able to accept external data we're
- 01:54:38 not doing this here yet
- 01:54:39 but then it simply has a build method
- 01:54:42 that builds
- 01:54:42 some widget tree it can't work with
- 01:54:46 internal data it can't change such
- 01:54:48 internal data therefore
- 01:54:50 and it will not recall build if some
- 01:54:53 data changed because it doesn't work
- 01:54:55 with internal data
- 01:54:58 it will only call build if it is created
- 01:55:00 for the first time
- 01:55:02 or if some external data which it
- 01:55:04 receives changes
- 01:55:06 now since we can't handle data with
- 01:55:08 stateless widget
- 01:55:09 it's the wrong widget for our purposes
- 01:55:11 here therefore
- 01:55:12 we need a state full widget
- 01:55:15 state can simply be translated as data
- 01:55:18 you're working with
- 01:55:20 data which you store in the widget and
- 01:55:22 which you also plan on changing
- 01:55:24 that is state now you already see
- 01:55:28 by changing this to a state full widget
- 01:55:30 we get red squiggly lines again
- 01:55:32 because we're missing a concrete
- 01:55:33 implementation of stateful widget
- 01:55:36 create state a stateful widget is indeed
- 01:55:39 constructed different to a stateless
- 01:55:41 widget
- 01:55:42 let's close the parentheses here to
- 01:55:44 close the class
- 01:55:46 definition for now of course our code is
- 01:55:48 now invalid
- 01:55:49 and let's add this create state function
- 01:55:52 by the way my ide already helped me and
- 01:55:55 automatically completed that
- 01:55:57 now this is how the create state
- 01:55:59 function should look like
- 01:56:01 as you can tell it returns a state
- 01:56:03 object
- 01:56:04 and here again we get these strange
- 01:56:06 angle brackets
- 01:56:08 this is called a generic type it allows
- 01:56:10 us to pass
- 01:56:11 extra information to another type and
- 01:56:13 here it tells us
- 01:56:14 that the state object and the state
- 01:56:17 class by the way is coming from the
- 01:56:18 flutter material package
- 01:56:20 that this state object will belong
- 01:56:24 to this stateful widget or to a stateful
- 01:56:27 widget in the end
- 01:56:28 because the way you work with state in
- 01:56:30 flutter
- 01:56:31 is that you actually create two classes
- 01:56:33 which will work together
- 01:56:35 and this is kind of the connection
- 01:56:36 createstate will return a new state
- 01:56:38 object
- 01:56:39 with a state that is configured to work
- 01:56:41 with a stateful widget
- 01:56:43 let's create that second class here you
- 01:56:46 should call it underscore my app
- 01:56:49 state now the underscore is just a
- 01:56:52 convention
- 01:56:53 for classes that should not be usable
- 01:56:57 by other parts or other files but only
- 01:56:59 from inside this file
- 01:57:01 and flutter will actually respect this
- 01:57:03 if you later work with multiple files
- 01:57:06 you will be able to import my app into
- 01:57:08 your file and use it but not
- 01:57:10 underscore my app state let's ignore
- 01:57:12 this for now though this is something
- 01:57:13 which will become clearer later
- 01:57:15 let's instead extend something again
- 01:57:18 because
- 01:57:18 since this should be a state object
- 01:57:20 understood by flutter it's not
- 01:57:22 surprising that you need to extend
- 01:57:23 something offered by flutter
- 01:57:25 you need to extend the built-in state
- 01:57:27 class enter an opening curly brace
- 01:57:30 thereafter
- 01:57:31 and leave your build method here because
- 01:57:33 the state class provided by flutter
- 01:57:36 actually has a build method now we just
- 01:57:39 need to tell
- 01:57:40 flutter that this myappstate class
- 01:57:43 belongs to this myapp
- 01:57:45 widget and we do this by adding these
- 01:57:48 angle brackets after state again
- 01:57:50 and here we add the name of the class to
- 01:57:52 which this state belongs
- 01:57:54 and now the connection between the two
- 01:57:55 classes is set up
- 01:57:57 now myappstate as i said keeps the build
- 01:58:00 method
- 01:58:01 and my app needs to return my app state
- 01:58:05 now
- 01:58:05 so return underscore myapp state and
- 01:58:08 instantiate it
- 01:58:09 by adding the parentheses now the
- 01:58:12 stateful widget
- 01:58:13 creates a new state object based on our
- 01:58:16 own class
- 01:58:16 which extends state and has the build
- 01:58:18 method and flutter internally will call
- 01:58:21 that build method
- 01:58:22 for that stateful widget and this is
- 01:58:25 just a setup you have to memorize
- 01:58:26 this is how stateful widgets work in
- 01:58:28 flutter the question that remains
- 01:58:31 of course still is how can we now
- 01:58:33 actually work with that
- 01:58:35 and change our list of products let's
- 01:58:38 have a look at this
- 01:58:39 in the next lecture
- 01:58:44 we created a stateful widget but the
- 01:58:47 question is
- 01:58:48 how can we now manage and change data
- 01:58:50 inside of it
- 01:58:52 we do it in a very simple way we add a
- 01:58:54 so-called property
- 01:58:55 to the myappstate class here for that
- 01:58:59 let's add something inside of the class
- 01:59:01 definition
- 01:59:03 let's add a property named products the
- 01:59:06 name is up to you though
- 01:59:07 now products will be a list of let's say
- 01:59:11 strings for now so just a list of text
- 01:59:14 since start is a strongly typed language
- 01:59:17 let's add the type in front of it
- 01:59:19 and the type is list this is a type
- 01:59:22 shipping with dart
- 01:59:23 it is what i called an array earlier
- 01:59:25 it's called array in many other
- 01:59:27 programming languages
- 01:59:28 in dart it's just a list something like
- 01:59:31 this
- 01:59:31 column is a list here this is a list of
- 01:59:34 widgets
- 01:59:35 now list is a generic type so that we
- 01:59:38 can define
- 01:59:38 a list of what it will be and this
- 01:59:41 should be a list of
- 01:59:43 strings so let's add string as a type
- 01:59:45 here
- 01:59:46 and now products has to be such a list
- 01:59:50 of strings this defines the property
- 01:59:54 but it's empty right now now i actually
- 01:59:56 don't want to start with an empty list
- 01:59:58 instead let's create a new list by
- 02:00:00 adding an equal sign and then on the
- 02:00:02 right side
- 02:00:02 the square brackets and in there let's
- 02:00:05 add our first
- 02:00:05 item now let's name this food tester
- 02:00:09 a food tester obviously a bit of a more
- 02:00:11 creative
- 02:00:12 product i'm imagining some tool which we
- 02:00:15 can point at our food
- 02:00:16 to test its ingredients test if
- 02:00:19 it's past its time if we should still
- 02:00:21 eat it something like this
- 02:00:23 simply a bit of a more fancy product
- 02:00:25 we'll go back to more
- 02:00:26 normal products throughout the course
- 02:00:28 though but let's not worry about the
- 02:00:29 product for now
- 02:00:30 now we want to render that to the screen
- 02:00:34 by converting it into a list of such
- 02:00:36 cards down there and we can do this by
- 02:00:39 going down to our widget tree here
- 02:00:41 and remember that our children here
- 02:00:44 that's a list of widgets
- 02:00:46 still instead of using card like this
- 02:00:49 i can reach out to my products now by
- 02:00:52 the way
- 02:00:53 products this is now a property of our
- 02:00:55 class
- 02:00:56 since this is a class only used in that
- 02:00:58 file and this is a property only used in
- 02:01:01 this class
- 02:01:02 you should also add underscore at the
- 02:01:04 beginning of the name that's just
- 02:01:05 another convention
- 02:01:07 so let's use products now like this down
- 02:01:09 there
- 02:01:10 by the way if you're coming from another
- 02:01:12 programming language like javascript you
- 02:01:14 don't
- 02:01:15 use this dot product or anything like
- 02:01:16 that you can directly reference it
- 02:01:19 and here you can call a method on this
- 02:01:22 array or on this list
- 02:01:23 by adding a dot and then there for
- 02:01:25 example is a map
- 02:01:26 method this allows you to transform
- 02:01:29 every element
- 02:01:30 in that list into a new element and
- 02:01:32 return it
- 02:01:33 and we would return it here as a new
- 02:01:35 value in this list in
- 02:01:37 our column map takes a function as an
- 02:01:40 argument
- 02:01:41 which holds the transformation logic it
- 02:01:44 will receive the element as an input
- 02:01:46 and then you can use the fat arrow
- 02:01:48 notation here to define what should
- 02:01:50 happen with that element
- 02:01:51 and here what should happen is that it
- 02:01:54 should create a card based on that
- 02:01:55 element
- 02:01:56 so let's grab card here let's add it in
- 02:01:59 here
- 02:02:00 remove that comma at the end and now
- 02:02:02 what this does is
- 02:02:03 it takes every element in the products
- 02:02:05 list and converts it to a card
- 02:02:08 and now we can also output the text
- 02:02:10 which is actually stored here
- 02:02:11 because remember element will just be a
- 02:02:14 string
- 02:02:14 because our list is a list of strings
- 02:02:18 so if i go down there i can type element
- 02:02:21 here
- 02:02:22 referring to this element and it will
- 02:02:24 output it
- 02:02:26 one important note though you need to
- 02:02:28 wrap element between
- 02:02:29 parentheses so this is the argument list
- 02:02:32 for the function
- 02:02:32 this is the function body it's one
- 02:02:34 statement it spans across multiple lines
- 02:02:37 but ultimately it's just the creation of
- 02:02:38 card so it's one statement
- 02:02:41 and we pass element in there and we
- 02:02:42 output it as text
- 02:02:44 now we still have red squiggly lines
- 02:02:46 there because this actually returns a
- 02:02:48 type
- 02:02:48 iterable and we need a widget here
- 02:02:52 now we can't convert a list into a
- 02:02:54 single widget so what i will instead do
- 02:02:56 is
- 02:02:56 i will add another column so we already
- 02:02:58 have a column with a container
- 02:03:00 and now with another nested column which
- 02:03:02 is absolutely fine
- 02:03:04 so another column widget here which will
- 02:03:06 have children
- 02:03:07 and the children here that should be our
- 02:03:10 list of
- 02:03:11 cards so let's grab that code and
- 02:03:14 replace that widget array here
- 02:03:16 with that products list this still won't
- 02:03:19 work though
- 02:03:20 we need to convert it to a list by
- 02:03:22 calling the to
- 02:03:23 list method here and now with that we're
- 02:03:26 done
- 02:03:26 now we added a new column with its
- 02:03:28 children argument
- 02:03:29 and there we have our products which we
- 02:03:31 map into a new
- 02:03:33 so-called iterable with our product
- 02:03:36 cards
- 02:03:37 and then we call to list here to convert
- 02:03:40 this to a list which can be used
- 02:03:42 now if we save this and we go back we
- 02:03:44 again see
- 02:03:45 our card and now we made a huge step
- 02:03:48 forward
- 02:03:48 to connecting this button to adding more
- 02:03:51 elements as you will see
- 02:03:56 so we spent a lot of work on this
- 02:03:58 strange conversion and i will already
- 02:04:00 say that there is a better way of
- 02:04:01 rendering such lists by the way
- 02:04:03 for now let's stick to this one and
- 02:04:05 let's make sure that our button
- 02:04:07 now finally does something this button
- 02:04:10 should now change products and i said
- 02:04:13 that when this data changes
- 02:04:15 build will be executed again and then it
- 02:04:17 will actually again take the updated
- 02:04:19 products list
- 02:04:20 map it into an updated list of cards and
- 02:04:22 render this to the screen
- 02:04:24 so theoretically if we change products
- 02:04:27 we should also get more cards
- 02:04:29 so what we can do here is we can reach
- 02:04:31 out to products
- 02:04:32 and then there is the add method to add
- 02:04:35 a new value
- 02:04:36 since this is a list of strings we can
- 02:04:39 add a new string
- 02:04:40 for now a hard coded one so we worked
- 02:04:42 with our awesome
- 02:04:43 food tester certainly a creative product
- 02:04:46 now let's be even more creative let's
- 02:04:48 take the advanced food tester
- 02:04:50 our super tool which allows us to find
- 02:04:52 out even more helpful information
- 02:04:54 about our food add a semi-semicolon at
- 02:04:57 the end
- 02:04:58 if you save this and you add product
- 02:05:02 nothing happens right the reason for
- 02:05:04 this is that this is not how it works
- 02:05:07 it actually will change products and i
- 02:05:09 can prove this to you by calling
- 02:05:11 print products here this is just a
- 02:05:14 debugging function which will print it
- 02:05:15 to the console here at the bottom
- 02:05:17 and if i now save this and i click this
- 02:05:20 one time
- 02:05:22 you see at the bottom there is food
- 02:05:23 tester and advanced food tester
- 02:05:26 yet we only see one card here
- 02:05:29 the reason for this is that updating
- 02:05:32 data like this will change it but
- 02:05:36 flutter won't recognize it
- 02:05:37 it by default doesn't watch all your
- 02:05:40 data fields here
- 02:05:41 and then re-render whenever some of them
- 02:05:43 changes this would be very inefficient
- 02:05:46 instead you have to tell flutter that
- 02:05:48 you're changing
- 02:05:49 the data in your stateful widget or put
- 02:05:52 in other words that you're changing
- 02:05:54 its state and you do this by calling a
- 02:05:57 special method
- 02:05:58 the set state method it's provided by
- 02:06:02 the flutter package
- 02:06:03 and it requires an argument which is
- 02:06:06 also
- 02:06:06 a function and in this function here
- 02:06:10 you execute the code which should change
- 02:06:13 your data and
- 02:06:14 lead to a re-rendering of the app so
- 02:06:17 here i called products ad
- 02:06:19 don't need to print anymore and now if i
- 02:06:22 save this you will actually see that
- 02:06:25 automatically you see that second card
- 02:06:27 and a warning that it goes beyond the
- 02:06:30 scope of your page
- 02:06:31 this however is just a feature of hot
- 02:06:33 reload it essentially calls
- 02:06:35 set state for you so let's do a full
- 02:06:38 reload
- 02:06:38 and you can do this with control f5 this
- 02:06:41 will restart the app from scratch
- 02:06:44 and now if i click add product you see
- 02:06:46 the card appear
- 02:06:47 with that warning and i did mention that
- 02:06:50 there is a better way of
- 02:06:51 rendering a list because this list by
- 02:06:53 default is
- 02:06:54 not scrollable which is the issue here
- 02:06:57 but at least it worked at least a new
- 02:06:59 card was
- 02:07:01 added and whilst we can improve
- 02:07:04 that list regarding the scrolling
- 02:07:06 behavior
- 02:07:07 this already shows us how we can work
- 02:07:10 with stateful
- 02:07:11 widgets now let's mix that let's create
- 02:07:14 another stateless widget
- 02:07:16 and let's see how these widgets can
- 02:07:18 interact before we then of course later
- 02:07:20 also fix that issue regarding our
- 02:07:23 sub-optimal
- 02:07:24 list
- 02:07:29 we learned a lot about the widget basics
- 02:07:31 now it's all the time to
- 02:07:32 keep on practicing that and one thing
- 02:07:35 you typically do in flutter
- 02:07:36 apps is you don't put all your code in
- 02:07:39 one root widget like in the stateful
- 02:07:41 widget
- 02:07:41 or its state to be precise but you split
- 02:07:44 your app
- 02:07:45 into granular pieces into multiple
- 02:07:48 widgets
- 02:07:48 and you also distribute these across
- 02:07:50 multiple files
- 02:07:52 so that each widget and each file stays
- 02:07:55 readable and maintainable so
- 02:07:59 how can we do that with this widget
- 02:08:02 well we can split it up we got of course
- 02:08:05 a stateful widget which we need
- 02:08:07 to manage our cards our products
- 02:08:10 but if we are honest this stateful
- 02:08:13 widget is really just
- 02:08:14 starting here where we render that
- 02:08:15 column of cards the entire
- 02:08:18 rest the material app the scaffold the
- 02:08:20 app bar and even the button here
- 02:08:22 that is just a state full widget it
- 02:08:25 doesn't change
- 02:08:27 yes the button is the part which
- 02:08:29 triggers the state
- 02:08:30 change but we probably can do something
- 02:08:32 about this too
- 02:08:33 but in the end the button itself does
- 02:08:35 not change
- 02:08:37 so let's split this up let's create a
- 02:08:41 new
- 02:08:41 file here in the lib folder which should
- 02:08:44 be named
- 02:08:45 products.dart now the file name is up to
- 02:08:47 you but the convention is
- 02:08:49 to write it all lowercase if you have
- 02:08:51 multiple words
- 02:08:52 separate them with an underscore and of
- 02:08:54 course always
- 02:08:55 end with dot dart because that's the
- 02:08:57 programming language extension
- 02:09:00 now in that products.dart file i want to
- 02:09:03 render that
- 02:09:04 list of products so that column here
- 02:09:08 so we can essentially grab that column
- 02:09:11 make sure to select the right code here
- 02:09:14 and cut it not the column which also
- 02:09:16 holds the button but just the column
- 02:09:19 which holds our cards let's go to the
- 02:09:21 product start dart page and let's create
- 02:09:23 a new class
- 02:09:24 and i'll name it products
- 02:09:28 like this now i need to extend
- 02:09:32 something which is imported from flutter
- 02:09:34 again and that's important
- 02:09:35 you need to add that import to every new
- 02:09:38 file
- 02:09:38 because every file works standalone so
- 02:09:41 to say
- 02:09:41 so just because you imported the flutter
- 02:09:44 material package here doesn't mean
- 02:09:46 that you don't have to import it here
- 02:09:48 again so let's
- 02:09:49 import package colon
- 02:09:53 flutter slash material.dart
- 02:09:56 now we want to create a widget here i
- 02:09:58 simply want to
- 02:09:59 outsource that column logic into this
- 02:10:01 widget the question is
- 02:10:03 do we extend a state full or a state
- 02:10:05 last widget here
- 02:10:08 you can build it in both ways
- 02:10:11 however actually the more elegant ways
- 02:10:13 to use a state
- 02:10:14 less widget here and now this can be
- 02:10:17 confusing because i just said
- 02:10:19 that this column card is the only thing
- 02:10:21 with changes
- 02:10:22 and that's correct but the change of
- 02:10:24 data
- 02:10:25 actually happens somewhere else you
- 02:10:27 could argue
- 02:10:28 the products widget here just receives a
- 02:10:31 list
- 02:10:32 of products and that list might be
- 02:10:35 changed but it can be changed outside of
- 02:10:37 that products
- 02:10:38 widget here let me show you what i mean
- 02:10:41 let's first of all add that build method
- 02:10:44 i'll take some ide help here type build
- 02:10:47 get that auto suggestion and hit enter
- 02:10:49 and it gives me the entire method
- 02:10:51 and in here i will return my
- 02:10:55 cut code so the column with the products
- 02:10:58 and so on and obviously products doesn't
- 02:11:00 exist here
- 02:11:01 that is something we'll have to fix but
- 02:11:03 this is the widget code i want to use
- 02:11:05 here
- 02:11:06 and that comma has to go at the end
- 02:11:10 the question just is how do i get
- 02:11:12 products
- 02:11:13 into my products widget and that is what
- 02:11:16 i meant
- 02:11:17 this is data which we can actually
- 02:11:19 receive from
- 02:11:20 outside so from the place where we will
- 02:11:23 eventually use
- 02:11:24 our products we can do this by adding a
- 02:11:27 so-called
- 02:11:28 constructor here we add a constructor by
- 02:11:31 repeating the class name
- 02:11:32 and then adding parentheses and now you
- 02:11:35 can add
- 02:11:36 curly braces to define which code should
- 02:11:39 run
- 02:11:39 whenever this widget is created the
- 02:11:42 constructor l also has some other
- 02:11:44 features though
- 02:11:45 and we need one feature only it should
- 02:11:47 be able
- 02:11:48 to accept a list of products you can
- 02:11:51 name this argument whatever you want but
- 02:11:52 i'll name it products
- 02:11:54 and then i want to store it in a
- 02:11:56 property of that products class
- 02:11:58 so that we can use that property down
- 02:12:00 there
- 02:12:01 for that i'll use i'll add a new
- 02:12:05 property here my
- 02:12:07 [Music]
- 02:12:08 products property which will be a list
- 02:12:12 of strings again that hasn't changed and
- 02:12:14 it's uninitialized initially so there is
- 02:12:16 no value assigned
- 02:12:18 but then i want to store products in
- 02:12:20 this product's
- 02:12:22 property and dart offers a convenient
- 02:12:24 shortcut
- 02:12:25 if i type this dot products then it will
- 02:12:28 automatically
- 02:12:28 take the incoming argument and store it
- 02:12:32 in a property with the same name so in
- 02:12:34 this product's property that's just a
- 02:12:35 shortcut
- 02:12:36 now we need to add a semicolon here
- 02:12:38 after their constructor
- 02:12:40 and now this will allow us to pass data
- 02:12:42 into products
- 02:12:43 through its constructor bind it to
- 02:12:45 products here
- 02:12:46 and then remove the underscore because
- 02:12:49 it's now just called products
- 02:12:51 like this so now we have a
- 02:12:54 widget which theoretically is able to
- 02:12:56 get products and output them
- 02:12:59 but we're not using it and we also have
- 02:13:02 green squiggly lines here
- 02:13:03 now it tells us that everything in this
- 02:13:05 class should be immutable which means
- 02:13:08 not changeable because it wouldn't be
- 02:13:10 able to react to these changes anyways
- 02:13:12 it's a stateless widget and we
- 02:13:14 specifically have to mark this property
- 02:13:17 as unchangeable we do so by adding a
- 02:13:20 special keyword in front of it
- 02:13:22 the final keyword this is a dart feature
- 02:13:24 which simply tells
- 02:13:26 dart and therefore also flutter that the
- 02:13:28 value of products will never change
- 02:13:31 it will be initialized once with the
- 02:13:33 value we get from the constructor
- 02:13:34 but thereafter we will never change it
- 02:13:37 it would have worked without the
- 02:13:38 addition of final two
- 02:13:40 but just as with types this leads to
- 02:13:42 cleaner code
- 02:13:43 and makes it very clear that this is a
- 02:13:45 value which is only set
- 02:13:46 from the outside and if new data is
- 02:13:49 passed in from outside
- 02:13:50 it will simply replace the old value not
- 02:13:52 change it replace it
- 02:13:54 and then call build again with the
- 02:13:56 replaced value this is how it will work
- 02:13:59 this is our products widget
- 02:14:00 now in the next lectures we'll start
- 02:14:02 using it
- 02:14:07 we created that product widget let's now
- 02:14:10 go back to the main dart file where we
- 02:14:12 removed that code for rendering the
- 02:14:13 cards
- 02:14:14 here i now want to also strip out
- 02:14:17 another part to put it into its own
- 02:14:19 widget again
- 02:14:20 and that will be this container with the
- 02:14:22 button
- 02:14:24 i will create another new file which
- 02:14:26 i'll name
- 02:14:28 product underscore manager.dart the name
- 02:14:32 is up to you
- 02:14:33 but in there i plan to well manage my
- 02:14:35 products
- 02:14:36 so again let's import package flutter
- 02:14:39 material
- 02:14:40 that is the package you work with the
- 02:14:42 most as you can probably tell by now
- 02:14:44 let's create a class which i'll name
- 02:14:46 product manager to fit
- 02:14:48 the file name but again written in the
- 02:14:50 form you should write your
- 02:14:52 class names capitalized words
- 02:14:55 and then here i extend a state full
- 02:14:58 widget because here i now plan on
- 02:15:00 managing my list of products
- 02:15:02 and changing it the stateful widget
- 02:15:05 needs to create
- 02:15:06 state method which i add with the help
- 02:15:08 of my ide
- 02:15:09 and therefore we need to add a second
- 02:15:11 class the
- 02:15:12 underscore product manager
- 02:15:15 state class which extends state which is
- 02:15:18 a generic type
- 02:15:19 linking to product manager
- 02:15:23 this has the build method again added
- 02:15:26 with the help of my
- 02:15:27 ide and then in here i want to return so
- 02:15:31 in the build method
- 02:15:32 i want to return that code i just cut
- 02:15:34 out with the container here
- 02:15:36 here i indeed also want to
- 02:15:40 copy and paste my products list so let's
- 02:15:43 remove it from my app state
- 02:15:45 and add it to the product manager state
- 02:15:47 here this is the list
- 02:15:49 which we change with a click of the
- 02:15:50 button still so this hasn't changed
- 02:15:53 and remove that comma here at the end
- 02:15:55 reform it
- 02:15:56 this is now our product manager state
- 02:16:00 now of course we should use it we should
- 02:16:02 create it here
- 02:16:04 so return product manager state
- 02:16:08 that already is it this is the product
- 02:16:10 manager stateful which it created
- 02:16:12 however it's of course missing our
- 02:16:15 products widget we're still not using
- 02:16:17 that
- 02:16:17 i want to use it here in the product
- 02:16:19 manager
- 02:16:21 below my button here of course so let's
- 02:16:24 actually
- 02:16:25 return a column here instead
- 02:16:28 which has children one of them
- 02:16:32 in a list marked with square brackets
- 02:16:34 one of them is the container
- 02:16:37 after the container we close the list
- 02:16:39 and the column widget
- 02:16:41 but we add another element after our
- 02:16:44 container
- 02:16:45 and that should be our product widget
- 02:16:48 for it to be usable in this file we need
- 02:16:50 to import it
- 02:16:51 now it's a good practice to separate
- 02:16:53 that import from package related imports
- 02:16:55 so separate imports from your own files
- 02:16:58 from the imports pointing at package
- 02:16:59 features
- 02:17:00 so here i will then import and to import
- 02:17:02 something from your own file
- 02:17:04 you just add dot slash
- 02:17:07 if it's in the same folder or if it's in
- 02:17:10 folder one
- 02:17:11 level above you add dot dot slash to
- 02:17:13 navigate into there
- 02:17:14 in our case it's in the same folder dot
- 02:17:16 slash and then
- 02:17:18 products dart with the file extension
- 02:17:20 like this
- 02:17:22 now i'm importing product start and now
- 02:17:25 this allows me
- 02:17:26 down there to use products like this
- 02:17:30 so now let's use products and if we have
- 02:17:34 a look at
- 02:17:34 products we expect to get a list of
- 02:17:37 products that should be
- 02:17:38 rendered here now that of course is our
- 02:17:41 underscore products property here which
- 02:17:44 we change with a click of a button
- 02:17:46 so we pass that down to products and
- 02:17:49 since we call set state when changing it
- 02:17:51 it will re-render that build method here
- 02:17:54 and therefore
- 02:17:55 also re-render products here and pass
- 02:17:57 down the updated
- 02:17:59 products list which will lead to this
- 02:18:02 build method
- 02:18:02 in the product widget being called again
- 02:18:05 too
- 02:18:07 so this is our product manager with that
- 02:18:10 changed let's go back to the main dart
- 02:18:12 file and let's use the product manager
- 02:18:14 there
- 02:18:14 now we're not handling any state in the
- 02:18:17 main.dart file anymore
- 02:18:19 so we can turn this stateful widget back
- 02:18:22 to a state
- 02:18:23 less widget remove that create state
- 02:18:26 method
- 02:18:27 remove the state myappstate class down
- 02:18:30 there
- 02:18:30 and just add the overwritten build
- 02:18:32 method to the my app
- 02:18:34 style widget again the body is no longer
- 02:18:37 a column
- 02:18:37 instead here i now simply want to have
- 02:18:41 my product manager
- 02:18:42 for that let's import it pointing at the
- 02:18:45 file like this
- 02:18:47 let's import product manager
- 02:18:50 create an object based on it by adding
- 02:18:53 parentheses
- 02:18:54 and now if we save all of that and maybe
- 02:18:57 let's do a full restart with ctrl
- 02:18:59 f5 to remove all old state we might have
- 02:19:02 loaded
- 02:19:03 we see the same app as before and it
- 02:19:05 behaves as before
- 02:19:07 also with that error still but now
- 02:19:10 we have a cleaner structure with
- 02:19:12 multiple files
- 02:19:13 multiple widgets which would also be
- 02:19:15 reusable which is great
- 02:19:17 but which also make your code easier to
- 02:19:19 manage because now each
- 02:19:21 widget is relatively short and easy to
- 02:19:23 understand
- 02:19:24 and this is how you want to structure
- 02:19:26 your flutter apps you build user
- 02:19:28 interfaces
- 02:19:29 with these widgets with these user
- 02:19:31 interface components
- 02:19:33 and you wanna split them up across
- 02:19:35 multiple files
- 02:19:36 you wanna work with stateless and state
- 02:19:38 full widgets
- 02:19:39 use as many state less widgets as
- 02:19:42 possible
- 02:19:42 and have a few selected state full
- 02:19:45 widgets
- 02:19:46 which actually manage your data and
- 02:19:48 change the data
- 02:19:49 like our product manager does in this
- 02:19:51 case
- 02:19:56 we spent a lot of work on building these
- 02:19:58 widgets
- 02:19:59 and we're almost done with the core
- 02:20:01 basics there are two more things i want
- 02:20:03 to dive into
- 02:20:04 and one of them is what if our state
- 02:20:07 full widget also wants to receive some
- 02:20:10 data from outside
- 02:20:12 let me give you a concrete example we
- 02:20:14 got the food tester product we're
- 02:20:16 starting with in the product manager
- 02:20:18 now of course we can set it up like this
- 02:20:20 it's just some dummy hard-coded code
- 02:20:22 anyways
- 02:20:23 but let's say we actually don't want to
- 02:20:25 start with it
- 02:20:27 but we want to get that starting data
- 02:20:29 from
- 02:20:30 outside because we want to define our
- 02:20:32 initial set of products we're starting
- 02:20:35 in the main.dart file maybe because we
- 02:20:38 fetched it from a server here
- 02:20:39 and we will do all these things
- 02:20:41 throughout the course we'll reach out to
- 02:20:42 a backend and so on
- 02:20:44 so we want to send that data into the
- 02:20:47 product manager
- 02:20:48 from inside our main dart file we
- 02:20:51 learned how we can pass data down
- 02:20:53 we can pass it as an argument like we
- 02:20:55 pass products to our product widget
- 02:20:58 and we accept it in the receiving widget
- 02:21:01 by adding the constructor function
- 02:21:03 we can also do that with the product
- 02:21:05 manager here
- 02:21:07 the product manager and here it's
- 02:21:08 important that you use the class that
- 02:21:10 extends
- 02:21:11 stateful widget not the state but this
- 02:21:13 one is the class you use in your
- 02:21:15 widget right here we use product manager
- 02:21:18 so that you use this and there you add a
- 02:21:21 constructor by repeating the class name
- 02:21:23 and adding parentheses
- 02:21:24 now this constructor here should now be
- 02:21:27 able to receive
- 02:21:28 an argument in our case the starting
- 02:21:32 product let's say now i want to store
- 02:21:35 that
- 02:21:36 and i will store it in a property which
- 02:21:38 is of type string
- 02:21:39 starting product and again we can use
- 02:21:43 this
- 02:21:43 trick or shortcut with this starting
- 02:21:46 product to assign the value
- 02:21:48 now we got the green squidney lines that
- 02:21:50 this should be an
- 02:21:51 immutable class wait what isn't it a
- 02:21:54 stateful widget
- 02:21:55 stateful widgets are all about having
- 02:21:57 state where the data can change right
- 02:22:00 that's true but it changes in the state
- 02:22:02 class
- 02:22:03 not in the widget class the two are
- 02:22:05 linked together
- 02:22:07 but it still is a technically separated
- 02:22:10 object so the widget is a technically
- 02:22:12 separated object
- 02:22:14 so here we actually have to add final
- 02:22:17 starting product
- 02:22:18 is something we receive from outside and
- 02:22:21 the only
- 02:22:22 way to change it is to recall build in
- 02:22:24 the parent component
- 02:22:26 and therefore recreate that product
- 02:22:28 manager pass a new value for starting
- 02:22:30 product into it
- 02:22:31 and then assign that new value here
- 02:22:34 that's all fine the question just is how
- 02:22:37 do we use
- 02:22:38 that starting product now because
- 02:22:41 we got in the product manager but we
- 02:22:44 needed the product manager state
- 02:22:46 now you could have the idea that you
- 02:22:48 pass it down to the constructor
- 02:22:51 starting product and then you add
- 02:22:54 the constructor for product manager
- 02:22:55 state here and you store it here in
- 02:22:58 another
- 02:22:58 string that would work but it's very
- 02:23:01 cumbersome
- 02:23:02 creating that chain to pass down a data
- 02:23:06 not that great instead there is a useful
- 02:23:08 keyword
- 02:23:09 a property which is provided by the
- 02:23:11 state class
- 02:23:12 which remember is provided by flutter
- 02:23:15 material
- 02:23:17 so a helpful property which actually
- 02:23:20 gives you access
- 02:23:21 to all the properties of the widget that
- 02:23:25 belongs to the state
- 02:23:26 because i told you they are linked
- 02:23:28 together and flutter does some behind
- 02:23:30 the scenes work for you
- 02:23:31 that special property is named widget
- 02:23:34 and it allows you to access the
- 02:23:36 properties of your
- 02:23:38 parent widget or of your connected
- 02:23:40 widget like starting product
- 02:23:42 the problem just is you can't use it
- 02:23:44 here when you're initializing properties
- 02:23:47 you can only use it in methods of the
- 02:23:50 product manager state
- 02:23:51 simply due to the way that widget
- 02:23:53 property is initialized
- 02:23:55 that's no problem though because that is
- 02:23:57 the second thing i wanted to show you
- 02:23:59 the state object or class
- 02:24:03 also allows you to implement some
- 02:24:05 special methods
- 02:24:06 the init state method for example again
- 02:24:09 i let it autocomplete by the ide
- 02:24:12 and it has one interesting thing
- 02:24:15 it's also overriding a built-in method
- 02:24:17 of course but the interesting thing is
- 02:24:18 that super
- 02:24:19 thing super always refers to the base
- 02:24:22 class you're extending so to the state
- 02:24:24 class here
- 02:24:25 and it simply calls in its state on that
- 02:24:27 base class
- 02:24:28 to make sure that it is called there
- 02:24:31 even if you overwrite it
- 02:24:32 so don't delete that and make sure to
- 02:24:35 call it at the end
- 02:24:36 after you executed your code init state
- 02:24:39 will be called
- 02:24:41 whenever this state object is
- 02:24:44 created is initialized so whenever this
- 02:24:47 product manager widget
- 02:24:48 is drawn onto the screen for the first
- 02:24:51 time you could say
- 02:24:52 and here i can reach out to products and
- 02:24:55 call
- 02:24:56 add and the value i want to add now is
- 02:24:59 using that special widget
- 02:25:00 property i was referring to and there
- 02:25:03 the starting product
- 02:25:04 so widget is provided by the state
- 02:25:07 object
- 02:25:08 gives us access to the connected
- 02:25:10 stateful widget
- 02:25:11 and to its properties and therefore i
- 02:25:14 can safely access starting product here
- 02:25:17 add it to my products and init state
- 02:25:19 will execute
- 02:25:20 when this state is created so when build
- 02:25:23 runs
- 02:25:24 for the first time that code will
- 02:25:26 already have been executed
- 02:25:30 let's see this in action and for that we
- 02:25:32 need to go back to main dart
- 02:25:34 and pass that starting product to the
- 02:25:36 product manager because we are
- 02:25:37 expecting it as a value there so food
- 02:25:41 tester and then let's do after saving
- 02:25:44 let's do a full restart with ctrl
- 02:25:46 f5 to flush all existing state
- 02:25:49 and now if i add a product this still
- 02:25:52 works but i don't even need to do that
- 02:25:54 you will see that food tester is
- 02:25:56 displayed here
- 02:25:57 and that of course means that our logic
- 02:25:59 is working we
- 02:26:00 are passing this down and we are
- 02:26:03 accessing it
- 02:26:04 with widget starting product and if
- 02:26:06 you're wondering
- 02:26:07 why we are not calling set state here
- 02:26:11 even though whoopset state even though
- 02:26:14 we
- 02:26:14 are changing our state and you are right
- 02:26:18 if that is your assumption
- 02:26:19 well the reason why we don't call set
- 02:26:21 state here is because as i said
- 02:26:23 init state runs before build
- 02:26:27 runs and therefore there is no need to
- 02:26:30 tell flutter that the data changed
- 02:26:31 it didn't render something to the screen
- 02:26:33 already so there is no need to re-render
- 02:26:37 so that's important to know there is in
- 02:26:39 its state
- 02:26:40 some life cycle hook as it is called a
- 02:26:43 method you can use to execute code
- 02:26:45 when your state object is constructed
- 02:26:47 and there is this widget
- 02:26:49 property provided by the state which
- 02:26:52 gives you access
- 02:26:53 to the connected stateful widget
- 02:26:59 before we now move on and also learn how
- 02:27:02 we can debug flutter apps and
- 02:27:03 finally then all to fix our broken list
- 02:27:06 here
- 02:27:06 before we do that let me quickly show
- 02:27:09 you these life cycle hooks i was
- 02:27:10 referring to you
- 02:27:11 it's first of all important that there
- 02:27:14 are state lessons and stateful
- 02:27:15 widgets and that there is a difference
- 02:27:17 of course stateless widgets
- 02:27:20 are used to create a widget where you
- 02:27:22 render something to the ui
- 02:27:23 and you can pass data into them that is
- 02:27:26 what we're doing with the products
- 02:27:27 widget in our app thus far
- 02:27:29 and that data we pass in can change
- 02:27:31 externally and that's
- 02:27:33 also what's happening in our app we
- 02:27:35 change it in the product manager widget
- 02:27:38 and the ui of that stateless widget gets
- 02:27:40 re-rendered when the input data changes
- 02:27:44 now a stateful widget also is all about
- 02:27:46 returning a widget
- 02:27:47 where we render the ui where we as you
- 02:27:49 saw in the last lecture
- 02:27:51 can receive input data which might also
- 02:27:53 change externally we don't see that here
- 02:27:55 but that would be possible
- 02:27:57 and then we also additionally have that
- 02:27:59 internal state which we can change from
- 02:28:01 within the widget
- 02:28:02 which also will lead to a re-render so
- 02:28:04 both external data changes
- 02:28:06 as well as internal state changes will
- 02:28:09 lead to the ui being re-rendered
- 02:28:12 widgets have a life cycle a stateless
- 02:28:15 and a stateful widget
- 02:28:16 differ in the lifecycle though and with
- 02:28:19 lifecycle i mean
- 02:28:20 methods you can add to your classes
- 02:28:23 which will be executed for you
- 02:28:25 by flutter a stateless widget has the
- 02:28:28 constructor function which you can
- 02:28:29 execute
- 02:28:30 and then it has the build function to
- 02:28:32 draw something onto the screen
- 02:28:33 that is all these are the two functions
- 02:28:36 which will be called
- 02:28:37 in the life of a stateless widget build
- 02:28:40 can be called multiple times
- 02:28:41 whenever the external data changes
- 02:28:45 the constructor function is always
- 02:28:47 available in the state full widget
- 02:28:49 but there we then call init state
- 02:28:51 thereafter before we then call
- 02:28:53 build for the first time we can then
- 02:28:56 also call
- 02:28:57 set state from inside this build
- 02:29:00 function or
- 02:29:01 to be precise most of the time you call
- 02:29:03 it when something happened when a button
- 02:29:04 was pressed but also for example when an
- 02:29:06 http request finished
- 02:29:09 and that would then rebuild so it would
- 02:29:11 call build again
- 02:29:14 but you can also have some changes to
- 02:29:16 your external data in which case
- 02:29:18 did update widget would execute so if
- 02:29:20 you
- 02:29:21 pass data to your stateful widget as we
- 02:29:23 are doing it with the starting product
- 02:29:26 and you would change that data then did
- 02:29:28 update widget would execute
- 02:29:30 and then build would run again so it's a
- 02:29:32 more complex life cycle
- 02:29:34 but why don't we just have a look at
- 02:29:35 this in action
- 02:29:38 back in our code let's start with the
- 02:29:39 state less widget
- 02:29:41 the products widget there we have the
- 02:29:43 constructor
- 02:29:44 and we're using the shortcut to assign a
- 02:29:46 value to products
- 02:29:47 now we can re-add a constructor body
- 02:29:50 because this is a normal function in the
- 02:29:52 end
- 02:29:52 we have to remove the semicolon then
- 02:29:54 though and now this will execute
- 02:29:56 whenever this product widget is created
- 02:29:59 so i will print something to the console
- 02:30:01 here and i will print
- 02:30:04 products widget constructor
- 02:30:07 so that we can quickly see what was
- 02:30:09 executed
- 02:30:10 i'll copy that line and go to the build
- 02:30:13 method and in that build method before
- 02:30:15 we return
- 02:30:16 we can of course then execute code in
- 02:30:18 there here
- 02:30:19 i will also leave the product widget
- 02:30:21 stamp but then
- 02:30:23 build so that we can see when this
- 02:30:25 executed
- 02:30:26 with that if we save that and we
- 02:30:28 completely restart the app with ctrl f5
- 02:30:32 then we see our app here but in the
- 02:30:35 terminal down there
- 02:30:37 we see that the constructor gets called
- 02:30:38 first and then build gets called
- 02:30:41 now if i now click add product once
- 02:30:44 we see the images added and here we see
- 02:30:47 the error message because we go out of
- 02:30:49 the boundaries
- 02:30:50 let's ignore it for now if we now scroll
- 02:30:52 up and you might
- 02:30:54 be required to scroll up quite a bit
- 02:30:56 then we see an error
- 02:30:58 regarding well that we gotta go out of
- 02:31:00 the boundaries and
- 02:31:01 this unfortunately now hides the thing i
- 02:31:04 wanted to show you so let's get rid of
- 02:31:06 the error
- 02:31:06 for now by removing that image to save
- 02:31:09 some space
- 02:31:10 so that we can fit more elements onto
- 02:31:12 the screen before we get an error
- 02:31:14 let's perform a full restart again we
- 02:31:16 then see
- 02:31:17 constructor and build now if i go back
- 02:31:19 and i click add product
- 02:31:21 we don't see anything here but if i
- 02:31:23 click it again
- 02:31:25 simply because there's a delay of one
- 02:31:27 click for the print statement there
- 02:31:28 always
- 02:31:29 we now see constructor build is called
- 02:31:32 again
- 02:31:32 and that's important both is called
- 02:31:34 again because it really
- 02:31:36 reconstructed this entire widget when in
- 02:31:39 the product manager
- 02:31:40 we changed our products which led to
- 02:31:43 this build method being executed again
- 02:31:46 which then led to the products being
- 02:31:48 recreated
- 02:31:49 that's the first part but let's also see
- 02:31:52 what exactly happens in the product
- 02:31:53 manager
- 02:31:55 so let's first of all go to the product
- 02:31:57 manager constructor
- 02:31:58 so off the stateful widget let's add a
- 02:32:01 body and let's add our print statement
- 02:32:04 product manager widget constructor
- 02:32:08 let's copy that let's then maybe
- 02:32:11 toss this line into create state
- 02:32:14 so that we can also see when this
- 02:32:17 executes
- 02:32:20 and let's then go down to init state in
- 02:32:23 the
- 02:32:24 product manager state now
- 02:32:27 and let's add this line here product
- 02:32:29 manager
- 02:32:30 state init
- 02:32:34 state copy that line and let's go into
- 02:32:37 the build
- 02:32:38 method here to all the print when we
- 02:32:41 build here now let's save that and again
- 02:32:44 let's do a full restart and now
- 02:32:47 you already see this actually executed
- 02:32:50 just as before
- 02:32:51 before this restarted app gets printed
- 02:32:53 because it happens before we see
- 02:32:55 something on the screen for the first
- 02:32:56 time which is why we had that delay of
- 02:32:58 one extra click before
- 02:32:59 it's not actually a delay it's just that
- 02:33:01 the restarting is only done
- 02:33:03 once we got something onto the screen
- 02:33:05 but now we can see
- 02:33:07 here this is actually where we start we
- 02:33:09 call the constructor of the product
- 02:33:10 manager
- 02:33:11 which makes sense because in the
- 02:33:12 main.dart file where we start
- 02:33:14 we initialize or we add the product
- 02:33:16 manager before we use products because
- 02:33:18 products gets in used inside of the
- 02:33:20 product manager
- 02:33:21 so we call the constructor of the
- 02:33:23 product manager we call createstate
- 02:33:25 that as you would guess creates the
- 02:33:28 state and therefore
- 02:33:29 init state is called then we call
- 02:33:32 build in the state and since inside of
- 02:33:35 build of our
- 02:33:36 state we create the products here
- 02:33:39 we then call the constructor and the
- 02:33:41 build method of products
- 02:33:43 thus far this should be clear let's now
- 02:33:45 go back and click add product one time
- 02:33:48 if we go back we now see something
- 02:33:51 happened
- 02:33:52 this is where we left now product
- 02:33:55 manager
- 02:33:55 state build was executed again because
- 02:33:58 of set state
- 02:33:59 this does not reconstruct the product
- 02:34:02 manager widget
- 02:34:03 which is why we don't see this
- 02:34:06 constructor or create state being
- 02:34:08 executed again
- 02:34:09 but it did re-execute the build method
- 02:34:11 of the state
- 02:34:12 and since we re-executed this products
- 02:34:15 was rebuilt
- 02:34:16 and therefore the constructor and the
- 02:34:18 build method in the products which it
- 02:34:20 was called
- 02:34:21 and by the way all that rebuilding
- 02:34:23 happens in a very efficient way
- 02:34:26 flutter takes care to not just redraw
- 02:34:28 the entire app
- 02:34:29 but really check what needs to be
- 02:34:32 changed so even if build is executed it
- 02:34:34 compares the
- 02:34:36 new and updated ui it will draw to the
- 02:34:39 old one
- 02:34:40 and only change the parts that need to
- 02:34:42 be changed
- 02:34:43 to make sure that this is done in a very
- 02:34:45 performance efficient way
- 02:34:48 this is the life cycle you should
- 02:34:49 understand now there's one extra thing i
- 02:34:52 want to show you as part of that life
- 02:34:54 cycle
- 02:34:55 in the product manager state here you
- 02:34:57 can also add the did
- 02:34:59 update widget method this
- 02:35:03 will be executed whenever your connected
- 02:35:05 widget
- 02:35:06 the product manager receives new
- 02:35:09 external data
- 02:35:11 now in our app right now this is not
- 02:35:13 happening let me
- 02:35:14 still add a print statement here
- 02:35:18 did update widget and by the way please
- 02:35:22 recognize that we also get old widget
- 02:35:25 which is the equivalent to that widget
- 02:35:27 keyword which we're all
- 02:35:28 using here but now not referring to the
- 02:35:31 updated widget with the updated external
- 02:35:33 data received you can get that updated
- 02:35:36 data on the widget keyword
- 02:35:37 but instead the old widget so the data
- 02:35:41 as it was in the old widget just in case
- 02:35:43 you would need that
- 02:35:44 maybe to compare the updated data to the
- 02:35:46 old one anything like that
- 02:35:49 the cool thing is if we do a hot reload
- 02:35:54 we actually see that update widget being
- 02:35:56 called here because a hot reload
- 02:35:58 in the end just calls set state for the
- 02:36:01 entire app
- 02:36:02 so it fakes this starting
- 02:36:05 text this food tester being changed even
- 02:36:07 though it didn't
- 02:36:08 it fakes that this happened because it
- 02:36:10 calls set state for the entire app to
- 02:36:12 re-render it
- 02:36:13 and therefore we see did update widget
- 02:36:16 is called
- 02:36:17 before we again build in the product
- 02:36:19 manager state
- 02:36:21 so this can be a useful place if your
- 02:36:23 state belongs to a widget
- 02:36:25 which receives external data that might
- 02:36:28 change
- 02:36:29 if you want to do something upon such a
- 02:36:34 change
- 02:36:36 that was a lot about widgets now
- 02:36:39 all these widgets use the material
- 02:36:41 design
- 02:36:42 now what is the material designed it
- 02:36:45 looks something like this you might
- 02:36:46 notice
- 02:36:47 it's google's design system which you
- 02:36:49 see in a lot of google applications
- 02:36:51 both on the web and on mobile now whilst
- 02:36:54 developed by google it's not just
- 02:36:57 google's design for everyone
- 02:36:59 instead material is a design system with
- 02:37:02 a lot of
- 02:37:03 guides best practices color combinations
- 02:37:06 that work well
- 02:37:07 in certain looks and fields of user
- 02:37:10 interface components
- 02:37:11 that you can use for mobile apps and web
- 02:37:13 apps and desktop apps
- 02:37:15 everywhere you can use it and it's of
- 02:37:18 course embraced by google but it's also
- 02:37:20 opened up to be less googlish and more
- 02:37:23 customizable so therefore using it in
- 02:37:27 ios apps is
- 02:37:28 also great and flutter actually uses
- 02:37:30 material design
- 02:37:32 you can still adjust your look to all
- 02:37:34 the look like ios cupertino styles
- 02:37:36 and that is something i will also show
- 02:37:38 you later in this course but we will
- 02:37:40 start with that material look
- 02:37:42 because it's important to understand
- 02:37:43 that it's not google's style for
- 02:37:45 everyone
- 02:37:46 it's indeed highly customizable as you
- 02:37:48 will learn
- 02:37:49 and material design as i mentioned is
- 02:37:52 built into flutter
- 02:37:53 and therefore we will use it and we will
- 02:37:55 get this
- 02:37:56 nice design i like it at least for the
- 02:37:59 app
- 02:38:00 out of the box without us having to do
- 02:38:02 any design work
- 02:38:04 now i mentioned that we can adjust our
- 02:38:06 theme and that we can adjust the looks
- 02:38:08 now we can do it in the main dart file
- 02:38:11 in our material app
- 02:38:13 there we can add another argument the
- 02:38:16 theme
- 02:38:16 argument and we pass in a theme data
- 02:38:19 object this also is imported from
- 02:38:22 flutter material
- 02:38:24 theme data takes a bunch of different
- 02:38:26 colors and styles we can set
- 02:38:29 like for example very important the
- 02:38:31 primary swatch
- 02:38:33 a swatch is a set of colors where we
- 02:38:35 define one color
- 02:38:36 and all the other colors will be
- 02:38:38 inferred automatically that's very
- 02:38:40 convenient
- 02:38:41 we can assign a color by using colors
- 02:38:44 a special object provided by the flutter
- 02:38:47 package
- 02:38:48 and there we can access so-called static
- 02:38:50 types
- 02:38:51 so basically properties we can access
- 02:38:54 without instantiating colors so we don't
- 02:38:57 add parentheses here
- 02:38:58 we call something directly on the class
- 02:39:02 and here we can for example add deep
- 02:39:05 orange if we now save this
- 02:39:09 you see that the app bar automatically
- 02:39:11 is orange and it will not just be the
- 02:39:13 app bar
- 02:39:14 it'll be a bunch of other things in the
- 02:39:15 application too
- 02:39:17 for example if you want to give that
- 02:39:18 button that look we can go to the
- 02:39:21 product manager
- 02:39:22 which is where we use that button and in
- 02:39:25 there
- 02:39:26 we can go to that button and there we'll
- 02:39:29 have a color
- 02:39:31 argument we can pass and there we can
- 02:39:33 now use our theme
- 02:39:35 by using a special object provided by
- 02:39:37 flutter which is called theme
- 02:39:39 which has a off method where we now pass
- 02:39:42 this context because this context
- 02:39:44 stores metadata information like the
- 02:39:47 general theme of our app
- 02:39:49 so we pass that to a theme and then we
- 02:39:51 can access for example
- 02:39:53 primary color here and if we now save
- 02:39:55 this
- 02:39:56 this button now alls is orange so that's
- 02:39:59 pretty convenient
- 02:40:01 let me by the way also re-add that image
- 02:40:04 because i don't care about the broken
- 02:40:05 list anymore just want to have that
- 02:40:07 image back
- 02:40:08 so that is how we can use the theme and
- 02:40:10 we can add more than just the
- 02:40:12 primary swatch we can set a dedicated
- 02:40:15 accent color for example
- 02:40:17 i will use colors deep purple throughout
- 02:40:20 this course because in my opinion purple
- 02:40:22 fits really well
- 02:40:23 to orange you can also set the
- 02:40:26 brightness of your app you don't need to
- 02:40:28 because the default is alright
- 02:40:29 but there you can access the brightness
- 02:40:31 object and there either the dark
- 02:40:33 or light static property if i choose
- 02:40:37 dark which is not the default
- 02:40:39 you see now we have a dark look dark
- 02:40:41 background
- 02:40:42 primary color also was overwritten if i
- 02:40:45 choose
- 02:40:46 light however then we're back to the
- 02:40:48 default mode
- 02:40:49 where we use the colors where we have a
- 02:40:51 white background but you can use both
- 02:40:53 which is really convenient
- 02:40:54 and you can do more feel free to play
- 02:40:56 around with the different things you can
- 02:40:58 set here
- 02:40:59 most of them should be pretty
- 02:41:01 descriptive especially
- 02:41:03 once you're done with the course so this
- 02:41:05 is the material design
- 02:41:06 and how you can adjust it you can always
- 02:41:09 adjust it to look more like ios
- 02:41:11 with less drop shadows and so on but
- 02:41:13 that is something i'll come back to in a
- 02:41:15 dedicated module
- 02:41:16 later in the course
- 02:41:21 with the themes added let me come back
- 02:41:24 to dart to the language we're using
- 02:41:26 because with the themes we use these
- 02:41:28 static properties as
- 02:41:30 i said now what is a static property a
- 02:41:32 static property
- 02:41:34 looks like this we can have a look at
- 02:41:36 the colors object
- 02:41:37 by holding command or control and
- 02:41:39 clicking on it
- 02:41:40 and most ides should offer such a
- 02:41:42 feature this lets
- 02:41:44 us look into the file which is added by
- 02:41:46 the flutter package
- 02:41:48 and here we actually see how such a
- 02:41:50 static property is defined
- 02:41:52 with the static keyword in front of the
- 02:41:55 name
- 02:41:55 and const is for now let's say the same
- 02:41:58 as
- 02:41:59 final it's a little bit different but in
- 02:42:01 the end it means it's a value which
- 02:42:02 won't
- 02:42:03 change and this is how we define a
- 02:42:05 static property named transparent
- 02:42:07 and here we got all the properties we
- 02:42:09 can import black
- 02:42:11 and if we search for it we'll also find
- 02:42:13 deep
- 02:42:14 orange here it is
- 02:42:17 there we got the static constant of type
- 02:42:19 material color which is just an
- 02:42:21 internal type deep orange so this is
- 02:42:24 another feature of dart
- 02:42:26 we can define static properties which
- 02:42:28 are properties we can import from a
- 02:42:30 class
- 02:42:31 without instantiating the class so
- 02:42:33 without executing the constructor
- 02:42:36 now whatever feature we already used but
- 02:42:38 which i also want to show you how to
- 02:42:40 create it on your own
- 02:42:41 are named arguments we're using it in
- 02:42:44 the main.dart file here for example the
- 02:42:46 arguments we pass to themedata
- 02:42:48 they all have a name name colon and then
- 02:42:51 the value for the name
- 02:42:52 now thus far we and our constructors for
- 02:42:55 example
- 02:42:56 and in our methods we only use
- 02:42:57 positional arguments
- 02:42:59 like in the product manager the product
- 02:43:01 manager constructor here
- 02:43:03 this starting product is a positional
- 02:43:06 argument because the first
- 02:43:08 value passed to product manager so in
- 02:43:10 the main.dart file this
- 02:43:12 string is stored away in this
- 02:43:15 starting product now if you only got one
- 02:43:18 or two
- 02:43:19 arguments using that makes sense but
- 02:43:21 maybe you got
- 02:43:22 multiple arguments and you want to
- 02:43:24 target them by name
- 02:43:26 to also allow you to not set values for
- 02:43:28 some of them
- 02:43:30 then you can wrap this in curly braces
- 02:43:33 and now it already is a named argument
- 02:43:36 just as easy as that
- 02:43:39 now we can pass a value by targeting
- 02:43:42 starting product here then a colon and
- 02:43:45 then the value
- 02:43:46 so now we're targeting this argument
- 02:43:49 named
- 02:43:50 startingproduct because we chose the
- 02:43:52 name here and
- 02:43:53 we passed the value to it and set it to
- 02:43:56 this
- 02:43:56 final string here
- 02:43:59 we could also set a default value by
- 02:44:02 adding an equal sign
- 02:44:04 time to switch the product and let's
- 02:44:06 move on to a sweets
- 02:44:07 tester now the sweets tester as the name
- 02:44:10 suggests
- 02:44:11 is a specialized tool for testing sweets
- 02:44:14 for their
- 02:44:14 ingredients how healthy or unhealthy
- 02:44:17 they are things like
- 02:44:18 that and now this would allow us to
- 02:44:20 actually
- 02:44:21 omit this value before i was getting an
- 02:44:24 error
- 02:44:24 now this is perfectly fine because if we
- 02:44:27 now do a full restart
- 02:44:29 we see we start with sweets tester but
- 02:44:32 we can overwrite it
- 02:44:33 by reintroducing our targeted named
- 02:44:36 argument
- 02:44:37 and now if we do a full restart
- 02:44:41 we start with food tester again so
- 02:44:43 optional arguments
- 02:44:45 that's also something you can do you can
- 02:44:47 also set optional arguments
- 02:44:49 for positional arguments
- 02:44:52 like for our products here let's say if
- 02:44:55 we wanted to start
- 02:44:56 with an empty list here by default you
- 02:44:59 can add an equal sign
- 02:45:00 and then the value you want to start
- 02:45:01 with if it's optional however
- 02:45:04 you also need to wrap the entire
- 02:45:06 argument assignment here with square
- 02:45:08 brackets
- 02:45:09 for named ones you use curly braces in
- 02:45:11 both cases
- 02:45:12 for positional one only optional ones
- 02:45:14 are wrapped but then
- 02:45:15 with square brackets now here i'm
- 02:45:18 getting red's quickly lines that this
- 02:45:20 must be a constant
- 02:45:21 and that's a special dart feature again
- 02:45:23 we have to add the const keyword here
- 02:45:25 which means
- 02:45:26 this is a list which can't be changed so
- 02:45:29 now you can't call
- 02:45:30 add or so on the products list here
- 02:45:34 this is what we now store here and this
- 02:45:37 means that now for product manager
- 02:45:39 we don't actually have to pass products
- 02:45:42 we can remove that
- 02:45:43 do a full app restart
- 02:45:48 and then of course we don't render
- 02:45:50 anything and our app is broken because
- 02:45:52 we don't pass the products which we're
- 02:45:53 changing down to the products
- 02:45:55 but it would work it doesn't make that
- 02:45:57 much sense here so let me re-add this
- 02:45:59 because we certainly want to pass our
- 02:46:01 products to the products widget here
- 02:46:03 but you can use such optional arguments
- 02:46:06 and throughout the course
- 02:46:07 we will build more and more methods and
- 02:46:09 also use these features
- 02:46:10 i just want you to know what's happening
- 02:46:12 behind the scenes here
- 02:46:14 so there were some additional dart
- 02:46:16 features which i felt important
- 02:46:18 to be mentioned at this point and whilst
- 02:46:22 i do
- 02:46:22 try my best to cover a lot of the dart
- 02:46:25 features which we use here and explain
- 02:46:27 them
- 02:46:27 if you want to learn everything about
- 02:46:29 dart also visit
- 02:46:31 dartlang.org that's the official dart
- 02:46:33 language page
- 02:46:34 and there you can for example take the
- 02:46:36 language tour to
- 02:46:38 get a detailed overview over everything
- 02:46:40 you need to know about dart
- 02:46:42 how it works which keywords it has how
- 02:46:44 you create var variables
- 02:46:46 what this difference between final and
- 02:46:48 const is how you create classes
- 02:46:50 what generics are and so on so check out
- 02:46:53 this page if you want to learn
- 02:46:54 everything about dart but again i will
- 02:46:57 reiterate and explain the core concepts
- 02:47:00 we are using
- 02:47:01 when we are using them
- 02:47:06 in this module we learned so much about
- 02:47:09 the widgets and the basics of a flood
- 02:47:11 wrap
- 02:47:12 it's certainly a lot of information to
- 02:47:14 digest so definitely go back and forth
- 02:47:16 and reiterate through the concepts here
- 02:47:19 we'll also use them throughout the
- 02:47:20 course so that should become clearer
- 02:47:23 now it's time to practice the most
- 02:47:24 important concepts though
- 02:47:26 so here's your first assignment create a
- 02:47:29 new flutter app you're starting with an
- 02:47:31 empty project you find it attached to
- 02:47:33 this video
- 02:47:34 or you simply create a new project and
- 02:47:36 empty the main.dart file
- 02:47:39 so you start with this project and i
- 02:47:41 want you to create a new flutter app
- 02:47:43 so create that root widget
- 02:47:46 which you learned how to create and so
- 02:47:48 on so create that
- 02:47:49 and make sure that you have an app bar
- 02:47:52 on that page you're starting with and
- 02:47:53 some text below it
- 02:47:55 now in the second step you should then
- 02:47:57 add a button which changes that text
- 02:47:59 and simply change it to another
- 02:48:01 hard-coded text
- 02:48:02 no user input at this point we'll add it
- 02:48:05 later but it's a bit more complex
- 02:48:07 so just some hard-coded text and step
- 02:48:10 number three then is to split your app
- 02:48:11 which
- 02:48:12 probably sits in one widget thus far
- 02:48:15 into three widgets
- 02:48:16 the app widget the text control widget
- 02:48:18 which also contains the button
- 02:48:20 and then a widget for outputting the
- 02:48:22 text now this will be a very granular
- 02:48:24 split which
- 02:48:25 might not make that much sense because
- 02:48:28 you probably will not have that many
- 02:48:30 widgets
- 02:48:30 in the text widget but still it's about
- 02:48:33 practicing these things practicing how
- 02:48:35 you can pass data around
- 02:48:37 and so on so that is your task
- 02:48:41 it contains only things we learned in
- 02:48:43 this module so definitely go back to
- 02:48:46 earlier lectures if you need to practice
- 02:48:48 some things again
- 02:48:49 and of course compare your solution to
- 02:48:51 mine which you find in the solution part
- 02:48:53 to my solution video
- 02:48:55 where i will walk you through my
- 02:48:56 solution
- 02:48:59 so let's solve that assignment here are
- 02:49:02 our tasks
- 02:49:02 i'll leave them there and we start by
- 02:49:05 first of all importing
- 02:49:07 package flatter material because that
- 02:49:10 material.dart file contains everything
- 02:49:12 we typically need
- 02:49:14 then we need a class my app you can name
- 02:49:18 it whatever you want but often that
- 02:49:19 root widget is called myapp and here
- 02:49:23 whoops without parentheses here i will
- 02:49:25 then extend
- 02:49:26 a state less or full well let's start
- 02:49:30 with a state last widget because we just
- 02:49:32 need to output an app bar
- 02:49:33 and some text so nothing to change right
- 02:49:36 now
- 02:49:37 so let's start with a state last widget
- 02:49:39 here and you learned that there we need
- 02:49:40 to add that build method
- 02:49:42 which receives the build context as an
- 02:49:45 argument
- 02:49:46 and which then returns a widget
- 02:49:49 and therefore it's a good practice to
- 02:49:51 define that type
- 02:49:53 in front of the build method and let's
- 02:49:55 also mark it as
- 02:49:57 overwritten so that this is really clear
- 02:49:59 that we're overwriting a built-in
- 02:50:01 method now here we need to return
- 02:50:03 something and since it will be our
- 02:50:05 root widget we return a material app
- 02:50:08 first of all
- 02:50:09 which does all that core wire up work
- 02:50:12 allows us to define a theme things like
- 02:50:14 that
- 02:50:15 i will not define a theme though though
- 02:50:18 you of course are free to do that
- 02:50:20 i will just add the home screen so the
- 02:50:22 first widget the first
- 02:50:23 content which should be displayed and
- 02:50:26 there i want to
- 02:50:28 create a complete page with the app bar
- 02:50:30 with the background
- 02:50:31 and for that we use the scaffold widget
- 02:50:34 which also ships with flutter
- 02:50:37 now the scaffold widget should hold that
- 02:50:40 app bar
- 02:50:41 and that body so let's target app bar
- 02:50:44 and add the built in app bar widget
- 02:50:47 which has
- 02:50:48 the title argument we can set and the
- 02:50:50 title should be a number widget it's a
- 02:50:52 text widget here and i'll just say
- 02:50:54 assignment 1 here we don't just want to
- 02:50:57 have the app
- 02:50:58 bar though we'll also add the body to
- 02:51:00 the scaffold
- 02:51:01 and that will now be that text i want to
- 02:51:03 have
- 02:51:04 now you can't just add text like this i
- 02:51:07 will actually use
- 02:51:08 the container here or even use center
- 02:51:11 which you
- 02:51:11 haven't learned about so i don't expect
- 02:51:13 you to know this center will simply just
- 02:51:16 center a value
- 02:51:17 horizontally and vertically it also
- 02:51:19 takes a child
- 02:51:20 and then the widget which should be
- 02:51:22 centered so center is of course built
- 02:51:24 into flutter
- 02:51:25 and there i will have my text this is
- 02:51:28 the
- 02:51:28 first assignment maybe the text is
- 02:51:31 totally up to you
- 02:51:33 with that we got our first widget
- 02:51:35 created again using center here
- 02:51:37 is optional just using the text would be
- 02:51:39 fine
- 02:51:40 and now to draw it onto the screen when
- 02:51:43 the app starts
- 02:51:45 we have to add one important thing and
- 02:51:47 that is
- 02:51:50 the main method let's add main here
- 02:51:53 and in there if you remember which you
- 02:51:55 should otherwise it won't work
- 02:51:57 you have to call run app and to run app
- 02:52:00 you pass the widget you want to create
- 02:52:03 so my app
- 02:52:04 with parentheses to construct an object
- 02:52:07 based
- 02:52:07 on that class and now you should be able
- 02:52:10 to see something on the screen
- 02:52:12 you might need to do a full restart here
- 02:52:14 after such drastic changes
- 02:52:17 and in my case this is not enough
- 02:52:19 because i still have that old
- 02:52:21 application running
- 02:52:22 so we'll just quit my debugging process
- 02:52:25 and then hit ctrl 5 to start it again
- 02:52:28 this will now build the project again
- 02:52:30 and ship it onto the virtual device
- 02:52:32 which can take a couple of seconds
- 02:52:35 and once this is done then we here got
- 02:52:38 our
- 02:52:38 finished app or for now finished app
- 02:52:40 running on the emulator with the app bar
- 02:52:42 and the center text again the centering
- 02:52:45 of course was
- 02:52:46 optional task number two is to now add a
- 02:52:49 button which allows us to change that
- 02:52:52 text to add a button we first of all
- 02:52:54 need to be able to render more than one
- 02:52:56 widget so let me use a column
- 02:53:00 for that and i will actually use a
- 02:53:02 column
- 02:53:03 instead of center because the two
- 02:53:06 actually won't work well together
- 02:53:08 anyways i will have my children then
- 02:53:11 and i will wrap the text in that list
- 02:53:14 now
- 02:53:15 of course i don't just want to have the
- 02:53:17 text i will have that button and i will
- 02:53:19 use a raised button
- 02:53:20 there are other buttons too but i will
- 02:53:22 again reuse raise button here
- 02:53:24 it will hold a child with the content of
- 02:53:26 the button which in my case will be some
- 02:53:28 text
- 02:53:29 where i say change text because that is
- 02:53:31 what will happen when you click that
- 02:53:32 button
- 02:53:33 and don't forget that on pressed
- 02:53:35 argument where you pass the reference to
- 02:53:38 a function
- 02:53:38 for now a function that doesn't do
- 02:53:40 anything
- 02:53:42 with that it's now all up in the top
- 02:53:44 well that is something we can change
- 02:53:46 later if we want but we get that button
- 02:53:48 which of course
- 02:53:49 doesn't do anything now what do we need
- 02:53:52 to do
- 02:53:52 to make that button do something
- 02:53:55 well we need to add code to that
- 02:53:57 function here in
- 02:53:58 on pressed but of course in a stateless
- 02:54:01 widget
- 02:54:02 we'll never be able to change our code
- 02:54:05 or to change our data so let's turn this
- 02:54:08 into a state full widget
- 02:54:10 which we can now close that first class
- 02:54:12 let's close it
- 02:54:13 and let's create another class the
- 02:54:15 underscore my app
- 02:54:17 state whoops my app state class
- 02:54:20 which extends state which is a generic
- 02:54:23 object
- 02:54:24 referring to my app to create that link
- 02:54:26 which will then have this build method
- 02:54:29 and in the my app widget we add create
- 02:54:32 state autocompleted by my ide which will
- 02:54:35 return a state which
- 02:54:37 links to a stateful widget and there
- 02:54:40 we return a new instance of my app state
- 02:54:42 like this
- 02:54:44 this now is a state full widget and it
- 02:54:47 allows us to add a property to
- 02:54:49 myappstate which we can
- 02:54:50 change from inside there so here i will
- 02:54:53 have my
- 02:54:55 let's say main text you can name this
- 02:54:56 whatever you want it's of type string
- 02:54:59 and initially let's say it's an empty
- 02:55:02 string or no let's say initially it's
- 02:55:05 this text of course because that is the
- 02:55:07 text we want to start with
- 02:55:09 so let's add it here now main text is a
- 02:55:12 property
- 02:55:13 should be underscore main text by the
- 02:55:15 way as per the dart convention
- 02:55:17 main text is now a property i can use in
- 02:55:20 that state class
- 02:55:21 and i want to use it down there in this
- 02:55:23 text i will not
- 02:55:24 output a string or i will output one but
- 02:55:26 not with quotation marks instead i will
- 02:55:28 refer to the main text property
- 02:55:30 which of course is this string
- 02:55:33 and now we can change it when we click
- 02:55:35 the button there
- 02:55:37 we can call set state that's important
- 02:55:40 otherwise the ui will not rebuild
- 02:55:42 and then in there i set main
- 02:55:46 text equal to this changed
- 02:55:51 and now if i save that and perform a
- 02:55:53 full restart
- 02:55:54 with ctrl f5 this is often required
- 02:55:57 after
- 02:55:58 you changed something drastic like this
- 02:56:00 where you turned your state
- 02:56:02 last widget in the stated full one now
- 02:56:04 if you click change text
- 02:56:06 you see this changed and the positioning
- 02:56:08 change because the button is
- 02:56:10 automatically centered
- 02:56:11 with the other content on the page and
- 02:56:13 since that content got shorter
- 02:56:15 well it's further to the left
- 02:56:18 this is now our button changing the text
- 02:56:21 only once or actually it will reset it
- 02:56:25 to this
- 02:56:26 change but we don't see that change of
- 02:56:27 course and that is task number two
- 02:56:30 solved already let's move on to task
- 02:56:33 number three
- 02:56:34 and this is a bit of a redundant task it
- 02:56:36 would be perfectly fine to keep that all
- 02:56:38 in one widget but
- 02:56:40 to practice that we'll split it up into
- 02:56:42 free
- 02:56:43 the app widget which we have should then
- 02:56:46 contain a text control widget which will
- 02:56:48 contain
- 02:56:49 the text widget so let's add two new
- 02:56:52 files
- 02:56:53 text underscore control dot dart and
- 02:56:56 text output i'll name it text output and
- 02:57:00 not text because there already is a
- 02:57:02 built in
- 02:57:03 text widget so to not clash with the
- 02:57:05 names i'll use a different one
- 02:57:08 and now let's go back to main dart and
- 02:57:11 let's grab
- 02:57:12 the column here
- 02:57:16 in our body of that scaffold let's put
- 02:57:18 it into the text control
- 02:57:20 there we first of all need to import
- 02:57:23 from the
- 02:57:24 flutter package from the material dart
- 02:57:26 file there
- 02:57:27 then we create a class text control
- 02:57:30 which will extend a state
- 02:57:32 full widget here because i want to
- 02:57:35 manage my text in there
- 02:57:38 that means that i add create state of
- 02:57:40 course and that we need to add a second
- 02:57:42 class
- 02:57:43 underscore text control state
- 02:57:46 which extends state which points at
- 02:57:50 text control
- 02:57:53 and there we will have the build method
- 02:57:56 and in the build method
- 02:57:57 well there we will return what i just
- 02:57:59 cut from the main
- 02:58:01 dart file this column where we have the
- 02:58:04 button and the text
- 02:58:05 now the main text property is missing we
- 02:58:07 can use that from main dart 2.
- 02:58:09 so there let's copy or cut the main text
- 02:58:13 move it into the text control state like
- 02:58:15 this
- 02:58:16 and now this is working again up there
- 02:58:19 text control that is also
- 02:58:21 almost looking great but of course in
- 02:58:23 create state we need to create a new
- 02:58:25 instance of the text control state
- 02:58:27 class we created here so now we get the
- 02:58:29 text control widget added
- 02:58:31 with the widget itself and our state
- 02:58:34 which holds our column
- 02:58:36 now we also got the text output widget
- 02:58:38 now i said this will be a bit redundant
- 02:58:40 because it will just hold
- 02:58:42 well this text widget which already is
- 02:58:45 just one widget i guess
- 02:58:47 but to practice passing around data
- 02:58:49 let's
- 02:58:50 still encapsulate it in our own widget
- 02:58:53 so let's go to text output
- 02:58:55 there again let's import package flutter
- 02:58:59 package flutter material dart
- 02:59:04 let's create a class text output
- 02:59:07 again not named text to not clash with
- 02:59:10 the built in text widget
- 02:59:12 it extends the state less widget here
- 02:59:15 because it will only receive data not
- 02:59:17 change it internally to receive data we
- 02:59:20 need to add a constructor
- 02:59:22 text output and then we need a property
- 02:59:24 to store the data we're getting
- 02:59:26 this will be a final property named
- 02:59:31 main text for example it will be
- 02:59:34 a string and initially it's undefined
- 02:59:37 but here we'll then target it with this
- 02:59:40 main text this by the way is one of the
- 02:59:42 few places where you use the this
- 02:59:44 keyword
- 02:59:45 for the shortcut and then we need that
- 02:59:47 build method of course
- 02:59:49 ide completes it for me and we just
- 02:59:52 return
- 02:59:52 text where we refer to main text like
- 02:59:55 this
- 02:59:57 this is our text output widget again a
- 03:00:00 little bit of a redundant
- 03:00:01 change but good for practicing now in
- 03:00:03 text control
- 03:00:04 i want to use that text output so i need
- 03:00:07 to import it
- 03:00:09 so let's add an import statement
- 03:00:10 pointing at text output dot
- 03:00:12 dart and with that we're importing
- 03:00:15 everything from that file so we're
- 03:00:17 importing that class
- 03:00:18 and we can use it down here to
- 03:00:22 pass text output and pass our main text
- 03:00:25 into it
- 03:00:26 so that this can get rendered now the
- 03:00:28 last thing is to now also connect
- 03:00:30 our text control widget here to the main
- 03:00:33 dart file
- 03:00:35 so in the main dart file let's import
- 03:00:37 from text control
- 03:00:38 let's import text control
- 03:00:42 like this now we can use that text
- 03:00:45 control widget here
- 03:00:47 and now in the main dart file i want to
- 03:00:49 use it and i will first of all
- 03:00:51 convert this back to a stateless widget
- 03:00:54 because i don't manage state in my root
- 03:00:56 app anymore
- 03:00:57 we can then get rid of create state and
- 03:01:00 of that class definition down there
- 03:01:02 and just add the overwritten build
- 03:01:04 method to my app
- 03:01:06 and in there i will then add this now
- 03:01:08 imported
- 03:01:09 text control widget which in this case
- 03:01:12 doesn't receive any arguments because
- 03:01:13 it's not configured to do so
- 03:01:16 and with all of that if you save and
- 03:01:18 then do a full
- 03:01:19 restart
- 03:01:22 you can go back to your app and it
- 03:01:24 should behave as before
- 03:01:26 now we got that split up and now we got
- 03:01:28 these core features
- 03:01:30 practiced now there's so much more you
- 03:01:32 can do with flutter
- 03:01:33 regarding the output on the layout of
- 03:01:36 your pages
- 03:01:37 so much more you can do and we will do
- 03:01:40 but the basics the very basics
- 03:01:42 should now be set
- 03:01:47 now that we also practiced the basics
- 03:01:50 about widgets and how we pass data
- 03:01:52 around let's dive into
- 03:01:54 an advanced example we got our product
- 03:01:57 manager
- 03:01:58 and there in the widget tree we
- 03:01:59 obviously got our
- 03:02:01 raised button now there is no specific
- 03:02:04 need
- 03:02:05 to move that raised button into a
- 03:02:08 different component let me say that
- 03:02:10 it's perfectly fine to have it in the
- 03:02:12 product manager but let's assume
- 03:02:14 we have this button in a more complex
- 03:02:17 widget
- 03:02:17 we also have a title there maybe some
- 03:02:20 image
- 03:02:21 so for some reason we outsource this
- 03:02:23 raised button
- 03:02:24 into its own widget let's quickly do
- 03:02:27 that i'll cut it from the product
- 03:02:28 manager
- 03:02:29 and add a new widget and i'll name it
- 03:02:31 product control
- 03:02:33 dot dart for now now in the product
- 03:02:35 control i'll first of all import a
- 03:02:37 package
- 03:02:38 and that package will be flutter and
- 03:02:40 material.dart from that package
- 03:02:42 so far that's not surprising and in
- 03:02:45 there i want to create a new widget
- 03:02:47 the product control widget
- 03:02:50 and the obvious question is will this be
- 03:02:52 a state full or a stateless
- 03:02:54 widget and it will be a state last
- 03:02:56 widget because all i want
- 03:02:58 to do is i want to display that button
- 03:03:00 it will not even receive any external
- 03:03:02 data
- 03:03:02 it will really just render this button
- 03:03:05 statically so this is a widget where the
- 03:03:06 widget tree will never change
- 03:03:08 still it is a widget so we have to add
- 03:03:10 this build method where we overwrite the
- 03:03:12 built-in one
- 03:03:14 and now in here i want to return the
- 03:03:16 code i just cut
- 03:03:18 from my product manager so let's paste
- 03:03:20 it in the raised button
- 03:03:21 and obviously i can't call set state in
- 03:03:24 here now
- 03:03:24 the advanced food tester that's not
- 03:03:27 going to work
- 03:03:28 so what can i do about that
- 03:03:32 well the goal is to use that product
- 03:03:34 control here that product control widget
- 03:03:37 inside of the product manager so let's
- 03:03:39 start
- 03:03:40 and let's import it so i'll add an
- 03:03:42 import at the top and import my product
- 03:03:44 control.dart file
- 03:03:45 and then i'll go down and in my build
- 03:03:48 method here
- 03:03:49 i'll use my product control like this
- 03:03:51 i'll call the default constructor which
- 03:03:53 we don't
- 03:03:54 have to add explicitly which will give
- 03:03:56 me a new instance of this
- 03:03:57 class and therefore this new widget
- 03:03:59 object
- 03:04:00 now this would almost work but set state
- 03:04:04 is still not an option here now
- 03:04:05 obviously you could say let's turn the
- 03:04:07 stateless
- 03:04:08 widget here in the product control
- 03:04:09 widget to a state full widget
- 03:04:11 and then we can add this state class and
- 03:04:14 start managing the state
- 03:04:16 the problem just is i don't need the
- 03:04:18 state in the product control
- 03:04:20 i needed the product manager because
- 03:04:22 there i can pass it down to products
- 03:04:24 which is where i ultimately want to
- 03:04:26 receive that
- 03:04:27 so product manager should stay a state
- 03:04:29 full
- 03:04:30 widget because there i need that state
- 03:04:32 because there i connect to a widget
- 03:04:34 where i need to pass the information to
- 03:04:37 the products widget itself can't be
- 03:04:39 turned into a stateful
- 03:04:40 one because even though i need the
- 03:04:42 product information here
- 03:04:44 i don't change it in that widget so the
- 03:04:46 product manager really is the connection
- 03:04:48 between the product control
- 03:04:49 and the products and that's the first
- 03:04:51 important thing i want you to understand
- 03:04:53 this is also a concept called lifting
- 03:04:55 the state up
- 03:04:57 we want to manage the state in a widget
- 03:05:00 which has access
- 03:05:01 to all the widgets that either change it
- 03:05:04 like the product control
- 03:05:05 or require the widget state the data
- 03:05:08 we're changing
- 03:05:09 the products widget in our case so the
- 03:05:11 product manager
- 03:05:12 is the connecting widget which
- 03:05:16 reaches out to all these widgets that do
- 03:05:18 change or need the state
- 03:05:21 the question now just is how can i pass
- 03:05:23 the information
- 03:05:24 that this button was pressed in the
- 03:05:26 product control
- 03:05:27 up to the product manager so that i can
- 03:05:30 then set the state
- 03:05:31 in the product manager well
- 03:05:34 for that let's create a new method in
- 03:05:37 the state
- 03:05:38 object of our product manager state here
- 03:05:40 i'll edit below my
- 03:05:42 init state and the update widgets i'll
- 03:05:44 add a new method here
- 03:05:46 and this method will not return anything
- 03:05:49 so i'll add white as a return type
- 03:05:52 then it will start with an underscore
- 03:05:54 for the same reason why products start
- 03:05:56 with an underscore
- 03:05:57 it's a class which i only use in that
- 03:06:00 file and i don't want
- 03:06:01 anyone to import this class or directly
- 03:06:05 access the methods or
- 03:06:07 properties on this class i don't want
- 03:06:10 anyone to directly use that class except
- 03:06:12 for the product manager widget here
- 03:06:14 so i'll start with an underscore in the
- 03:06:16 name and i'll name it
- 03:06:18 update products and the name is totally
- 03:06:20 up to you so
- 03:06:21 update products in my case here
- 03:06:24 and i expect to get an argument here and
- 03:06:27 the argument
- 03:06:28 should be the new product let's maybe
- 03:06:30 name it add
- 03:06:31 product therefore that's even clearer so
- 03:06:33 here i will receive an argument
- 03:06:35 the product which i do want to add and
- 03:06:37 let's also define the type here to write
- 03:06:39 better code
- 03:06:40 let's add a string in front of the name
- 03:06:42 to be clear that this
- 03:06:44 method here will receive are an argument
- 03:06:47 which is a string now with that i'm
- 03:06:51 defining add product
- 03:06:52 and now i can go to the product control
- 03:06:54 and cut my set state code from there
- 03:06:57 because i can't use it there anyways
- 03:06:58 this is not a stateful widget
- 03:07:00 and move it into add product and now
- 03:07:03 here i don't want to add the advanced
- 03:07:05 food tester but the product which i'm
- 03:07:07 receiving as an
- 03:07:08 argument so an add product i'm now
- 03:07:11 calling set state
- 03:07:12 and i can do that here because i am in a
- 03:07:15 state
- 03:07:15 object belonging to a stateful widget
- 03:07:18 and i add the product which i receive as
- 03:07:20 an argument
- 03:07:22 the remaining problem is i want to call
- 03:07:24 add product
- 03:07:25 whenever this button is pressed but the
- 03:07:27 button lives in a different widget
- 03:07:29 how can we solve that that's the second
- 03:07:32 important thing i want you to take away
- 03:07:34 lifting the state up was one important
- 03:07:36 concept but now to give another widget
- 03:07:39 access to a method in this widget we can
- 03:07:42 simply pass a reference
- 03:07:44 down to the widget which should have
- 03:07:46 this access
- 03:07:47 so i can pass add product as an argument
- 03:07:50 to the product control please note i'm
- 03:07:54 not executing it i'm not adding
- 03:07:55 parentheses
- 03:07:56 why because i don't want to immediately
- 03:07:59 execute it if i would add parentheses
- 03:08:01 here
- 03:08:01 it would execute the method whatever the
- 03:08:03 build method runs
- 03:08:05 and it would only pass the return type
- 03:08:07 of that method to product control
- 03:08:09 which in this case is void so i don't
- 03:08:11 want to do that i don't want to pass the
- 03:08:12 return type
- 03:08:13 i want to pass a reference to this
- 03:08:16 function
- 03:08:16 so the function is not getting executed
- 03:08:18 yet we're just passing the address
- 03:08:21 to the function down to the product
- 03:08:22 control
- 03:08:24 now i can go to the product control and
- 03:08:26 expect this
- 03:08:27 as an argument to the constructor so i
- 03:08:30 will add the constructor here
- 03:08:32 and i want to receive that
- 03:08:36 function reference and store it in a
- 03:08:38 property of that class
- 03:08:40 for that i'll create a new final
- 03:08:42 property which should never change
- 03:08:43 except for when this widget is recreated
- 03:08:46 and i'll name it add product
- 03:08:49 you can give this any name you want and
- 03:08:51 you see it's not the same name as an
- 03:08:53 apparent widget though that would be
- 03:08:55 possible but here i don't have the
- 03:08:56 underscore
- 03:08:57 and i really just want to make clear
- 03:08:59 this can be named how you want
- 03:09:01 i can also define the type and the type
- 03:09:03 will be a function here
- 03:09:05 function is a separate type in dart
- 03:09:08 and it's simply well is what it sounds
- 03:09:10 like it means in this
- 03:09:12 property we'll store the reference to a
- 03:09:15 function
- 03:09:16 and that means that now here i can say
- 03:09:18 this add product
- 03:09:19 so whichever argument i receive in this
- 03:09:21 constructor will be bound to this
- 03:09:23 property and now we have access to a
- 03:09:26 function
- 03:09:27 in this widget even though we don't
- 03:09:29 define the function in this widget
- 03:09:31 and this means when this gets pressed i
- 03:09:33 can execute
- 03:09:35 add product and then also of course
- 03:09:38 pass on the argument because remember
- 03:09:41 add product
- 03:09:42 is a function that expects a string so
- 03:09:45 i want to pass a string and let's leave
- 03:09:47 the world of exotic products maybe
- 03:09:49 let's just name this sweets
- 03:09:53 because it's an image full of sweets if
- 03:09:56 we now
- 03:09:56 save that and do a full restart to clear
- 03:09:59 any
- 03:09:59 existing state this is our app and if i
- 03:10:02 click add product
- 03:10:04 we still add this new item
- 03:10:07 but now we're adding it from a button or
- 03:10:09 by clicking on a button
- 03:10:11 which lives in a different widget and
- 03:10:13 this is one advanced concept which i
- 03:10:15 want you to understand
- 03:10:17 that if you want to pass data up so if
- 03:10:20 you have something happening in a widget
- 03:10:22 and the parent widget needs to know
- 03:10:23 about it and the parent widget in our
- 03:10:25 case is the product manager
- 03:10:27 then you do that by passing down a
- 03:10:30 reference to a function
- 03:10:32 which executes in the parent widget this
- 03:10:34 is crucial to understand
- 03:10:40 now before we finally leave this module
- 03:10:42 of important basics
- 03:10:44 here's one important basic about the
- 03:10:46 dart language
- 03:10:47 so not something exclusive to flutter
- 03:10:49 but really to dart
- 03:10:50 in the product manager we have our list
- 03:10:53 of products here right
- 03:10:54 and we change this list of products
- 03:10:56 because we add new products here in set
- 03:10:58 state for example
- 03:11:00 now one thing we also saw in dart before
- 03:11:03 is that when we receive data via the
- 03:11:06 constructor
- 03:11:07 we typically bind this to a property
- 03:11:09 where we want to add the final
- 03:11:11 annotation
- 03:11:12 this is not required for the code to run
- 03:11:14 but flutter itself or dart
- 03:11:16 itself tells us that we should do this
- 03:11:18 because we get this warning
- 03:11:20 that this class is marked as immutable
- 03:11:22 and that is simply
- 03:11:24 happening because the stateless widget
- 03:11:25 is marked as such
- 03:11:27 and this simply tells us hey it's a good
- 03:11:29 practice to be clear about the fact
- 03:11:31 that the data you work with here is
- 03:11:33 immutable which means
- 03:11:34 you can't change it from inside because
- 03:11:36 that wouldn't have any effect here
- 03:11:38 anyways
- 03:11:39 now we can go back to the product
- 03:11:41 manager state
- 03:11:42 and there this might surprise you i can
- 03:11:46 go to my products list which we
- 03:11:47 certainly do
- 03:11:48 change and i can add final there too
- 03:11:51 and now if i save this and do a full
- 03:11:53 restart
- 03:11:55 and i go back to the app it still works
- 03:11:59 as before now why is that when i mark
- 03:12:01 this as final
- 03:12:03 why can we still add products and that's
- 03:12:05 something important to understand about
- 03:12:07 the dart
- 03:12:08 language and how it works
- 03:12:11 final indeed means this property here
- 03:12:15 is final we can't assign a new value
- 03:12:18 but that's the important thing when we
- 03:12:21 call
- 03:12:22 add on the existing list we're not
- 03:12:24 assigning a new list
- 03:12:26 we're editing the existing one but
- 03:12:29 that's important that's a concept called
- 03:12:31 reference types that only changes an
- 03:12:34 existing
- 03:12:35 object in memory it does not create a
- 03:12:38 new one
- 03:12:38 and hence it does not assign a new one
- 03:12:41 to products
- 03:12:42 it's a different thing for numbers by
- 03:12:44 the way if i had a number
- 03:12:46 8 here and it said let's say 42 and
- 03:12:48 that's not my age
- 03:12:50 but let's say that is our age and now
- 03:12:52 here in set state
- 03:12:53 i want to set age equal to 29 which is
- 03:12:56 my age
- 03:12:57 well then i get a warning here that age
- 03:12:59 can't be used as a setter because it is
- 03:13:01 final so we can't assign a new value and
- 03:13:04 it should be obvious what we're doing
- 03:13:06 here we're assigning a new value because
- 03:13:08 with the equal sign here
- 03:13:09 you won't see an equal sign here for
- 03:13:11 products and
- 03:13:12 therefore of course you would fail if
- 03:13:14 you say products
- 03:13:16 is now an array with one string
- 03:13:19 this would be a valid list it holds a
- 03:13:21 string and
- 03:13:22 product should be a list of strings but
- 03:13:25 we get the same
- 03:13:25 error as for the age we can't do that
- 03:13:28 because it's final
- 03:13:30 so assigning new values which requires
- 03:13:33 the equal sign
- 03:13:34 is not possible changing the existing
- 03:13:37 value is possible
- 03:13:38 because lists and objects in general
- 03:13:42 are reference types which means we only
- 03:13:46 store the reference to an object here
- 03:13:49 in products the reference to this array
- 03:13:51 and if we then use
- 03:13:52 methods on that object and this array or
- 03:13:56 list is also just an object everything
- 03:13:58 is an object in dart even a number
- 03:14:00 if we then call a method on that this is
- 03:14:03 okay
- 03:14:03 this changes the existing element but it
- 03:14:05 doesn't create and assign
- 03:14:07 a new one and that's the only thing
- 03:14:09 final prevents
- 03:14:11 and therefore for example if i take my
- 03:14:12 age again and i call a method on that
- 03:14:15 like round to round it well then you see
- 03:14:19 i don't get any errors there because it
- 03:14:21 has the same logic
- 03:14:22 i might be doing something with the
- 03:14:25 existing
- 03:14:26 number though round will return a new
- 03:14:28 value actually it doesn't change the old
- 03:14:30 one
- 03:14:31 but i can safely do that and i could do
- 03:14:33 anything on the number that changes it
- 03:14:35 if i don't reassign it to age
- 03:14:40 now that is a concept which can be
- 03:14:41 challenging to wrap your head around
- 03:14:43 but it's crucial to understand final
- 03:14:46 basically this allows us
- 03:14:47 to use the equal sign more than once
- 03:14:51 if we want to ensure that we also never
- 03:14:53 can change the value
- 03:14:55 with for example the add method
- 03:14:58 then there is another tool we can use in
- 03:15:00 dart and that is the const keyword
- 03:15:02 on the right side of the equal sign this
- 03:15:05 means
- 03:15:06 this value is now constant and therefore
- 03:15:09 if i now
- 03:15:09 save this and we do a full restart
- 03:15:14 you can already tell that there seems to
- 03:15:16 be some error and if i go back we indeed
- 03:15:18 see an error on the screen
- 03:15:20 unsupported operation cannot add to an
- 03:15:23 unmodifiable list
- 03:15:24 and that's pretty clear our list is
- 03:15:26 declared to be not
- 03:15:28 modifiable because of that const keyword
- 03:15:31 and therefore it already understands
- 03:15:34 that calling add here will be a problem
- 03:15:36 unfortunately it doesn't tell us in our
- 03:15:38 ide at least not in visual studio code
- 03:15:41 but we get that error once we run our
- 03:15:43 code even before i clicked anywhere
- 03:15:46 and we already get this because it's not
- 03:15:48 just happening when we call add product
- 03:15:51 it is already a problem when we try to
- 03:15:53 assign a value here in its state
- 03:15:55 there we call add for the first time and
- 03:15:58 there we already try to change a list
- 03:16:00 which is marked as unchangeable so if
- 03:16:03 you want to be sure
- 03:16:04 that a value can never be changed use
- 03:16:06 const
- 03:16:07 on the right side of the equal sign if
- 03:16:09 you just want to be sure
- 03:16:10 that you will never be able to assign a
- 03:16:12 new value to a property
- 03:16:14 then use final in front of the property
- 03:16:16 name
- 03:16:17 that might seem super advanced and a
- 03:16:20 little bit
- 03:16:21 unnecessary to understand but it is
- 03:16:23 syntax you will see a lot and i want you
- 03:16:25 to understand what's going on here
- 03:16:27 so let me remove const here and i'll
- 03:16:30 also remove
- 03:16:31 final because i don't care if we assign
- 03:16:33 a new value here or not
- 03:16:34 i just want you to understand what final
- 03:16:37 and cons to do
- 03:16:38 when added on left or right sign of the
- 03:16:41 equal sign
- 03:16:47 that's it for this module we learned a
- 03:16:49 lot about the important basics of
- 03:16:51 flutter
- 03:16:52 most importantly we learned that flutter
- 03:16:55 is all about
- 03:16:56 widgets and this is really something you
- 03:16:59 have to take away and you have to
- 03:17:02 get into your mind so to say flutter is
- 03:17:04 all about
- 03:17:05 widgets you compose the user interface
- 03:17:08 which you are seeing in your app
- 03:17:09 from a set of built-in widgets which you
- 03:17:12 can of course
- 03:17:13 also put together into your own custom
- 03:17:15 widgets
- 03:17:16 so that you get reusable ui components
- 03:17:20 which you can then use to build your
- 03:17:22 user interface
- 03:17:23 so it all comes down to these widgets
- 03:17:25 and you build this widget
- 03:17:27 tree remember you have that root widget
- 03:17:30 that material app widget which is
- 03:17:32 wrapped in your root widget
- 03:17:34 and then you got the scaffold widget for
- 03:17:36 a page and on that page you then have
- 03:17:38 the body with
- 03:17:39 all the other widgets where you have a
- 03:17:41 column which might have an
- 03:17:42 image and a text so this is how you
- 03:17:45 build
- 03:17:46 flatter apps and then you have stateless
- 03:17:49 widgets on the one hand
- 03:17:50 these are widgets that only take data as
- 03:17:53 an
- 03:17:54 input optionally they don't have to and
- 03:17:56 they return
- 03:17:57 a new widget tree they have this build
- 03:18:00 method which returns a widget or a tree
- 03:18:04 of widgets
- 03:18:05 and this tree of widgets can be affected
- 03:18:08 by external data which you receive with
- 03:18:10 the constructor
- 03:18:11 but this is not a must you could also
- 03:18:14 have a widget that works without any
- 03:18:16 external data
- 03:18:16 that just displays a static tree which
- 03:18:19 never changes
- 03:18:20 you also have state full widgets which
- 03:18:23 can also receive
- 03:18:24 external data just like the state less
- 03:18:26 widgets and they also will have
- 03:18:28 a build method though that lives in the
- 03:18:31 state object which belongs to these
- 03:18:33 widgets
- 03:18:34 but they can also well work with that
- 03:18:37 state object
- 03:18:38 they can manage internal data which they
- 03:18:41 can change
- 03:18:42 with set state which will also call
- 03:18:45 the build function again so which will
- 03:18:47 also lead
- 03:18:48 to the build method being executed and
- 03:18:50 the widget tree being re-rendered
- 03:18:52 because that's important changes to
- 03:18:55 external
- 03:18:56 or internal data in your widgets
- 03:18:59 lead to a re-render cycle so the build
- 03:19:01 method gets
- 03:19:02 re-executed and a new tree of widgets is
- 03:19:05 created
- 03:19:06 and flutter will then compare this new
- 03:19:08 tree to the old
- 03:19:10 tree which is already rendered onto the
- 03:19:12 screen and will render any differences
- 03:19:14 and
- 03:19:14 update your view we also used
- 03:19:18 dart and it's important to understand
- 03:19:20 how dart
- 03:19:21 relates to flutter dart is the
- 03:19:24 programming language used by flutter
- 03:19:26 it's not an alternative
- 03:19:27 it's just a programming language because
- 03:19:30 flutter
- 03:19:30 is both an sdk shipping with the tooling
- 03:19:33 you need to build native mobile apps
- 03:19:36 so the tooling you need to compile the
- 03:19:38 dart code
- 03:19:39 to native code so to say or wrap it
- 03:19:42 in native code but it also is a dart
- 03:19:45 framework
- 03:19:46 so it's not just a tooling it's also a
- 03:19:48 framework which offers a rich set of
- 03:19:50 classes and widgets you can use to build
- 03:19:52 your app
- 03:19:53 all these widgets we have been using
- 03:19:55 were exposed by flutter
- 03:19:57 dart is an object-oriented programming
- 03:19:59 language which means you work with
- 03:20:01 classes and you
- 03:20:03 instantiate these classes by calling
- 03:20:05 their constructor
- 03:20:06 and it also uses static typing which
- 03:20:09 simply means
- 03:20:10 you define which types of data get
- 03:20:13 stored in a variable
- 03:20:14 get returned by a function and so on
- 03:20:17 and check out that dart language tour i
- 03:20:20 was pointing you at
- 03:20:21 in this module to learn more about dart
- 03:20:24 if you want to dive
- 03:20:25 really deeply into it you will learn
- 03:20:27 more about it throughout this course
- 03:20:28 though
- 03:20:29 too now finally one important
- 03:20:32 part of working with flatter widgets is
- 03:20:35 that you can pass
- 03:20:36 data around and that you understand the
- 03:20:38 widget lifecycle
- 03:20:40 now you can pass data between widgets by
- 03:20:42 using their constructor methods
- 03:20:44 this is how you can pass data down the
- 03:20:46 widget tree you can pass
- 03:20:48 data to a child widget for stateful
- 03:20:51 widgets
- 03:20:51 data can also be passed from the widget
- 03:20:53 to the state object
- 03:20:54 because remember you create stateful
- 03:20:56 widgets by
- 03:20:58 connecting two classes basically you can
- 03:21:01 pass that with this special widget
- 03:21:03 property which gives you access
- 03:21:04 to the properties of the widget in your
- 03:21:07 state
- 03:21:08 and stateful widgets offer additional
- 03:21:10 lifecycle methods where you can execute
- 03:21:12 code
- 03:21:13 init state and did update widget these
- 03:21:15 will execute when certain things happen
- 03:21:17 in its state when the widget and its
- 03:21:19 state are first created
- 03:21:21 did update widget whenever the widget
- 03:21:23 receives new external data
- 03:21:25 and you can use these to run your code
- 03:21:28 up on these events
- 03:21:29 all widgets stateless and stateful ones
- 03:21:32 have the constructor and the build
- 03:21:33 method
- 03:21:34 the constructor is called when the
- 03:21:35 widget is created or re-rendered so if
- 03:21:38 the parent
- 03:21:39 tree of which this widget is part is
- 03:21:41 re-rendered
- 03:21:42 and the build method is then always
- 03:21:44 called when the widget is re-rendered
- 03:21:46 flatter needs the build method and the