Flutter Tutorial for Beginners: Layout Basics

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to my introduction to flutter for beginners in this tutorial you'll learn everything you need to know about creating basic layouts in flutter the material that you'll see here is part of my clutter and firebase course on udemy and this includes two full hours of content on building layouts and it shows you how to build this sign-in page from scratch so this is what you will learn in this video we will start from the basics and learn about material up and team data and how to create scuffles with an app bar and then we will cover the column and row widgets and see how to use the cross axis alignment and main axis alignment properties we will learn about how to add padding and how to create and customize text widgets as well as how to create custom buttons and customize their color shape and how to add images with logos inside them while doing this we will create our own custom button widget and learn how to design a good and ergonomic widget API and because this tutorial is for beginners we will take it nice and slow and just to be clear this tutorial dives straight into flatter and doesn't cover the dart language in detail so if you are new to that I recommend that you follow my introduction to dart which is freely available as a playlist on my youtube channel so I hope you enjoy the rest of this tutorial and make sure to LIKE and subscribe for more flutter videos and if you're serious about learning flutter and firebase you should consider enrolling in my full course which contains 22 hours of content and goes well beyond the basics and you can buy the course for a discounted price on my website at code Villandry accom or using the link in the description below ok so let's get started and learn about layout basics in flutter by the way this tutorial starts with the default canter application that you get when you create a new fluttered project so make sure that you have flutter already configured and installed on your system and that you have already created a new flutter project that you'll use to follow along okay so we are now ready to start and the first thing that we are going to do is to delete all the code next we need to import a specific file so that we have what we need in order to build our flapper up so the first thing we do is to type in import and then in single quotes we start typing material and Android studio is suggesting a package that we can import in here this is the correct one so we type enter and then next thing we want to do is to define the entry point of our application so here we can type void main and this is the main method of our app now in here we need to tell flutter to run our app so we're going to invoke a method which is called run up and we can see that it takes one parameter which is the root widget of our entire app so in a second we'll create a class for our root widget and we can really give it any name we want so here I'm just going to choose to call it my up just like that and when I do this understood your points out that this name is not yet defined and that's because we haven't declared it to be a class just yet alright so next I'm just going to go down here and what I want to do is to create a class which will extend stateless widget and that name of that class will be my app now I could just type in all of this manually but instead I'm going to use a really cool feature of Android studio which is called templates so what I can do is start typing in state less and I can see that under studio is proposing me a few different options so I'm gonna choose the first one and I can see that is now filled in all the template that is needed to create a stateless widget class so all I have left to do is just to type in the name of my class which is my app and I'm done okay so what I have here is a minimal flutter up and this is code that will already compiled in fact I can just try to hotter load the app and what I'm going to get is a black screen now just so you know this is completely expected and that's because even though we have created our widget we are not really showing anything interesting yet before we write any more code I want to explain a little bit more in detail what we have done so on the first line of this file we have imported the material file from the Futter package as we continue on this course we will often have to import things that are defined in other files so the place to put these imports is always at the top of the dart file the syntax of the dart import statement is always like this so you have one import keyword at the beginning and then within quotes you type in package colon and then the path to the file that you're after alright then we have to find the main method and every flutter up always requires a main method and inside it you always want to run up with the route widget of your app then we have created our first widget which is called my up and is a stateless widget and because of this it needs to implement a build method now here Android studio has inserted an override annotation for us what this does is tell the compiler that we've actually overriding a method on the superclass and in this case this is stateless widget the build method returns up widget and takes a build context as a parameter and we will see a bit later what the build context is for finally we return a container object here which is a very common flutter widget we will also explore this a little later okay so we are now ready to replace this black screen with something more interesting and we'll do that in the next video in the previous video we started building our up and we have created our first widget however the screen appears completely black in our simulator now we are going to build an app that uses material design for our UI so what we want to do here it is to use material of widget that we have seen before so rather than returning a container here we are going to say material up instead now if you remember this is a widget that takes a few properties and so we are going to add them now the first one is title so here we could just say something like Time Tracker then the second property that we want is a theme that will be used throughout the app and we define this by adding up team data object and this is something that has a number of different properties but the one that we're really interested in is called primary swatch and in here we want to define the primary color of our entire app so for now I'm just going to choose this to be colors dot indigo you can see here that the Android studio proposes a lot of different options so this is the one that I want to use for now okay next I need to define a home for my material up and this is going to be a widget because I haven't created the signing page yet for my up here I just want to have some kind of placeholder for the time being and so what I'm going to use right now again it's going to be a container which will be just empty now if I save and hot reload now I can see the nothing much has really changed and actually there is a little banner that has appeared over here to the top right and he says debug and this is just a useful visual hint to tell us that the app is being compiled in the back mode and debug mode is what allows us to use features such as hot reload in any case the app still doesn't look very interesting so one thing that we could try to do now would be to change the background color of the app so the way we can do that would be to other color property to our container and we can choose that by typing in colors dot for example white now I can save again and I can see that the app completely changes and it turns white now I still haven't explained what this container widget is but don't worry I won't keep it a secret for much longer for now just bear with me as we are going to start building the signing page in the next video in the previous videos we have created a very simple material up which shows a white background what we are going to do next is to lay the foundations for the first page of our time tracker up and it is going to be the signing page that we can see if I open the final up over here and the first thing that we need to decide is where we are going to store the code for that signing page in other words we can start thinking about a project structure that will allow our app to grow as we add more and more pages and features at this stage we could choose to keep writing code on this main dot dart file but this is not something that we want to do because we want to define a new class for our signing page and I think this deserves to be in his own file so the question is where do we put that file now I could just choose the lead folder over here and create a new file just like this but I'm going to suggest that this is not a good idea instead I'd like to keep all the widgets that are specific to certain pages or features in their own folder so what I'm going to do is to create a new folder and I can do that by selecting new package in Android studio and I'm going to call this up like this in addition to that I'm also going to create a subfolder called sign-in so I'm going to type that in and now I can see here like it seems that Android studio has decided to collapse together the up and signing folders into one item but if we look at the top over here we can see that we definitely have a folder called up and inside that we have another one called sign-in ok so we will see the adding functionality for signing in into the app will keep us busy for quite a while in this course and I expect that we'll end up with a few different files in here so now that we have this folder I'm going to create a new file dart file in fact and I call this sign-in page and I can continue on the next video we are now ready to start writing the code for our signing page so the first thing we are going to do is to create a signing page class as a stateless widget in the same way that we've done before so here we're just going to use the Android studio template for stateless widget and we're going to name this sign-in page now we can see that there's quite a lot of things that the compiler is not happy with and the reason for that is that we forgot to import the flutter packets that defines all these different symbols so we can fix this very quickly by placing our cursor for example on status widget and then pressing alt enter and here we are given a choice of imports that we can choose so we are going to select the material packet and we can see that all the warnings go away okay we have now defined our sign-in page and before we had any more coding here we must remember to actually add it to our root widget so what we are going to do is to head back to our main dart file and what we are going to do is replace this container with an instance of the signing page that we have just created so I'm going to type that in and put it like this and the compiler is now happy because although we have added it here we have forgot to import the correct file so like we have done before we can select this symbol and import the missing file by pressing alt enter and the editor just just the right thing to do so we are going to confirm that and then we have imported the signing page we are all clear now so just to check that everything still works we are going to run the app and while we wait for the app to start actually that was quite quick we can just quickly inspect the import line that has been added by unbury studio so what is done is add a package with name time tracker flutter course so this is the name of our packets and then it includes the up slash sign-in slash signing pay start file so this is the full path to our file that we have created within the time tracker flutter course packets okay so we can head back to our signing page and we can see also that the app still looks white so nothing in there to see at the moment now since we are going to present a natural page here we can make use of some of the useful UI elements that come out of the box with the scaffold widget so what we are going to doing here is to replace this container with the scaffold and the first thing that we want to add to our scaffold is an up bar so up bar define like this takes a number of interesting properties and one of them is called title which is a widget here we can define the title as a text and here we can type in time tracker so if we save this and reload we can see that at the top of our simulator indigo color bar is appearing and we now have this time tracker title in here now before we make any more progress I'd like to talk a little bit more about up bar and a do that in the next video in the last video we have added an up bar to our scaffold and as we can see is background color is set to indigo which is the main color of our app however we have not actually specified the color in the up bar itself so where does this come from so up bar is one of many widgets in flutter which inherits some other configuration from somewhere else so if we go back to our main file we can examine the primary swatch of our app and we can see that it uses the indigo color so at this stage you might guess that if we change this for example to brown and reload the app then the up bar changes and so this is exactly what happens so for now we are not going to investigate much in detail about how this works exactly but just so you know some widgets have the ability to load some of their properties directly from their ancestors and in particular this clean data object that we are created defines a lot of visual properties we can find this out if we tap through to reveal the documentation and here we find a long list of properties that are available for us to set up in addition all these properties are defined with some specific default values and we can see them all over here so for now the most important thing to know is that some widgets will inherit some of their visual properties from theme data whenever you ask yourself where does a certain color or textile come from it is likely that it is defined inside the team data object that you pass to the material up over here and this has a lot of properties that are set by default okay so we can restore the primary swatch back to indigo save and also get back to the sign-in page and before we move on I want to talk a little bit more but upward and I'll do that in the next video in the last video we have introduced an app bar widget to our sign-in page now app bar is a very useful and customizable widget that we can place at the top of the screen in some of the previous videos have told you that a good way to inspect the documentation for flutter widgets is to click through right from the editor however it is also good to know that the flutter documentation can be inspected online so if we now put up a browser and head to this address at Docs the fluttered IO we find the official flutter documentation this covers all the classes that are part of the flutter SDK as well as a lot of other packages that are often used when building flutter apps so at any time you can come back to this page and learn more about flutter and relevant packages for now I want to show you the documentation for the up bar class so I can do that by typing up bar on the search box over here and I am taken to this page which has a nice illustration about how app bar works so here we can see the app bar can show a number of different widgets in different positions and you can really use this in a number of different ways so for now we are only using the title property of the app bar but there is much more to that and we'll be using some other properties of app bar later in this course okay so that is what I wanted to say about up bar for now and we can head back to our editor and continue building our signing page okay so before we move on and start adding content to this page there is a little thing that I would like to change about this up bar and that is a property which is called elevation now this is a double number and elevation refers to the shadow that you can see under the up bar so we can try to edit this and see how the app changes so we can set up for example an elevation of 10 and if I save in hot reload I can see that the shadow is much more prominent or if I set this zero then the shadow completely disappears I believe there is a default value which is four but I think in this example I want to make it a little bit more subtle and so I'm going to try a value of two so just a very subtle shadow down there okay so I'm happy with this change and we are going to continue on the next video in the last video we have customized our up bar next we are going to figure out how to put some content on this page now just as a reminder our goal is to show a title and four different buttons which look like this so step one will be to try to get this look and feel for the buttons and step two will be to add functionality so that we can use these buttons to sign in the user but before we talk about buttons and how they work we need to talk a little bit about layout so what you see over here is a number of different widgets and they are all arranged vertically in our page so if we want our page to look like this we need to work out how we can place widgets vertically and in order to do this we need to use a widget which is called a column now here is what we are going to do next we are going to add a few widgets to our scaffold and our initial goal is to position these widgets so that they arranged vertically so for now we are now going to use buttons just yet and instead we are going to use some boxes of different colors in the process of doing that we are also going to learn how to add padding and spacing between widgets okay so we can get started in the next video okay so this white area over here on the screen is the content area of our scaffold and that is defined by a property which is called the body of the scaffold so if we define that we can add a widget to it and let's get started for now with just a container so we are going to type container and this is it just to show you that this container actually fills the whole content of the scaffold I can set a color for it and for example I could type colors the yellow and now that I've just restarted the app you can see that the whole content area is now yellow now remember that our immediate goal is to draw some boxes on the screen with different colors and we want to arrange them vertically so we have just learned that this can be done with a column widget but where can we put a column so it is time to talk about the most important property of container which is called child so I container can specify a widget child which could be any widget in flutter so what we are going to do now is to add a child which is actually a column and the column also has a very important property which is called children now children needs to be a list of widgets so it's not just one child but it is multiple children now how would we go about adding some boxes to this column well we have learned that we can use a container to specify a rectangular area and that it has a colored property so the first thing that we could try to do is to add a container like this and maybe we could set this color to colors the orange now if we try to hot Rollem now we can see that nothing happens and the reason for that is that our container does not have a child and so when we put it inside a column its size is actually zero and that means that the container itself is not this so somehow we want a way to add boxes to our column but we need to give them a size and there are multiple ways of adding widgets that have a size in flutter so for this case we want to use a new widget as the child of our container and the widget that we want to use is called a sized box now sized box is a widget that has two optional properties called width and height so let's try to add them and see what happens so I'm going to add a width of 100 and also a height of 100 also so if I hot reload at this point I can see that something strange happens so part of the screen has gone back to white some of it stayed yellow and I have this square box of color orange at the top so I need to explain a little bit more about what's going on over here and I'm going to do this in the next video in the last video we started adding some content to the body of our scaffold and the way we've done that is by adding a container with a yellow color and then we added a child column and because this takes a list of widgets then we try to add a container with a child size box inside it and then we have given it a width and a height of 100 points and the orange color for the container however after making the change we have observed that the result on screen was not quite what we had expected so the key for understanding what is happening here is to see how a column actually works and to illustrate this better let me open up a diagram okay so what we have here is a simple layout which is made by a yellow background so this is similar to our container and then there are three boxes which are laid out vertically we have learned that to arrange items vertically we need to use a column however to understand why things look differently on our screen we need to learn about two important properties of column which are called main axis alignment and cross axis alignment main axis alignment refers to how the children should be placed along the main axis of the column so in this case it is the vertical axis cross axis alignment refers to how the children should be placed along the cross axis of the column so in this case it is the horizontal axis each of these properties can be configured with a number of different values so if we go back to our code we can try to add a cross axis alignment value to our column and we can try to choose a value for it now there are a number of different values that you can choose and the editor is proposing them for us and the one that is actually set by default is called cross axis alignment start so if we are a lot here we can see that nothing changes on this layout okay so what we want to do here is to set the valley across axis alignment to stretch and if we do that and save we can see the suddenly we get the result that we were expecting and that is that the box stretches all the width of the screen okay so now that we have clarified that let's take a look again at this sized box widget that we have added over here so by specifying a width and a height or we are actually doing is to tell flutter that the desired dimensions of our size box are a hundred and a hundred but because this is inside a column with a cross axis alignment of stretch then the width parameter no longer applies and instead the size of the box is going to fit the entire width of the column now this is exactly what we want because we shouldn't need to specify width for a widget that should match the width of its parent in other words we can drop the width of this box and leave the height only and if we can save and see that this works now you might wonder what would that happen if we try to set the cross axis alignment value to something else for example center or maybe end and what would happen here is not what you might expect and I don't want to make things confusing at this stage so for now I'll put this back and please just bear with me because in the coming videos we'll get a better understanding about column and flexible layouts in general so for now let's just carry on the next thing that we can try to do is to add a new size box which represents the second vertical item in our layout so we're going to continue on the next video okay so in a moment we will continue from where we left another new box to our layout but before I do that I want to draw your attention to one little thing and that is the way this code is formatted now normally when you pass parameters to functions these are always separated by commas so for example here I have a nav bar and I passing the title and the elevation parameters and I have a comma at the end of each parameter now what you would do in other languages is to not have this comma on the last parameter however one very important thing to note is that the way in which you use commas in dart is going to affect how your code is formatted so what do I mean by that as you can see on this file the way we build our widgets in flutter is by composition so for example here we have a container and inside it there is a column and then inside we have another container and finally a size box this is still a relatively simple layout however if you look at the way this code is formatted it looks a little bit like a pyramid of sorts like this and this is something that helps us keep track of the widget hierarchy that we're building in addition to that our code editor is adding for us some annotations at the end of each closing bracket so for each closing bracket over here we can see - which widget it refers to so what am I going with all of this now this is a good time to introduce a comment called dart format and you can choose this comment by opening up the code menu over here and going all the way down here to reformat code with our format now be aware that there is also another line here called reformat code so make sure you choose the correct one which is called reformat code with dart format and by the way on my system I've added a custom shortcut to access this quickly so that here I can just press alt command l and I can format my code so after doing this you can see that the code reformatted and the way dart format does this is based upon where you put the Commons in your code so what I'm going to suggest going forward is that we always add comments at the end of parameter lists so what this means for this code specifically is that here for example I had forgotten to put the comma at the end of my column and so after formatting the two closing brackets for column and container or folded together so what I'm going to do is to add a comma here and then run that format again and you can see that the indentation has now changed so just to give you another preview of how using commas affects your indentation here I could remove this comma at the end of the up bar and if I format again I can now see that the hole up bar has been indented and and put just on one line so for the remainder of this course you see me use commas very often and the reason for that is the flutter widgets often take a lot of different parameters so I think separating them line by line keeps the code much more readable okay so now that we clarified that I can add the missing comma over here and I'm also going to add this one over here so that we have done all alright so before we move on I just want to mention that if you want to customize your keyboard shortcuts in Android studio you can just go here on the menu select preferences and here you find a key map item and on the right all the menus that are on the menu bar up here you can just see them open them up and then you can select your own key maps for each one of the items that you want to change all right so we can close this and if you are using Android studio by all means you can spend some time customizing your shortcuts okay so we have managed to add our first box to our column layout and we are ready to add the second one all right so to create a new box I'm going to select this section and I'm going to copy and paste it into a new box like this I'm also going to change the color of the container to red and if I hot reload I can see that now the second box has appeared as well alright so maybe let's take this step one step further and maybe create a third box which maybe I can color with the colored purple and if I hot rollout here it is so it looks like we have now managed to build a vertical layout which was our original goal so with the code that we have over here we can add boxes set their color and also set their height one thing that we can see over here is that the body of our scaffold is getting bigger and bigger and really I think it would be a good idea here to extract all of this code into a separate metal so what we are going to do now is to move all this code to a new method and I'm going to show you how to do this with a couple of tricks so the first one is going to be about code selection so here for example I could just place my cursor on this sized box and then I'm going to press alt + up arrow multiple times and I can do this to extend the selection of the enclosing scope so I can carry on and do this until I reach the body of my scaffold which is over here then I'm going to use a new command which is called extract - method and in my system I've mapped this to alt comment and so when I press that I get a little dialog which asks me to choose a method name so I'm going to call this build content and when I press Enter what happens is that all the code that I had selected has now been placed into a new man called build content and this method is now called from within the body of my scaffold as you can see the built metal of our signing page is now much more readable and it's easier to see that it just creates a scaffold with an up bar and then the body is now specified with this new build content method over here we can see the Android studio as defined this method with a return type of container and this is because a container is the root widget of this entire block of code in the future am I decided rather than returning a container am i return some other kind of widget and for this reason I'm just going to change the return type to be a widget like this now this is safe to do for two reasons one is that a container is actually a subclass of widget so I can change the return type to be a widget and the other one is that the body of mine scaffold actually requires a widget nothing more specific than that so very often when I extract arbitrary widget hierarchies such as this one I will take care of setting the return value of the extracted method to widget okay so we now have this new method for building the content of our page however there is one small change that I still want to add to this method and I'll do that in the next video in the last video we have extracted some of our widget building code into a separate method called build content now before we move forward I want to do another small change to the name of this method so what I'm going to do is to select the method and then I'm going to rename it so I can do that by pressing shift of 6 and the way I'm going to rename this is to add an underscore at the beginning like this so why did I do this the reason is the underscore has a special meaning in dart so here it goes underscore means private so whenever we declare anything in dart and we put an underscore at the beginning that symbol becomes private and what do I mean by private so in dart private symbols are symbols that are only accessible inside the file that they are declared in and so to show you what I mean I here I could go back to the main file and I could maybe create a new instance of the signing page such as this so I could type in sign-in page equals sign in page just like this and then I could try to type in sign-in page dot well I could try to call build content which is the way the metal is called but the editor doesn't even give me access to that in the first place so it says that built content isn't the fine for the class signing page and the reason is that I made that method private so if I went back here and I change these once again to be public by removing the underscore I could go to the main method over here and now we can see that the code would compile and the and the editor is happy with it all right so let me clear this up then I can go back to the sign-in page and make this metal private once again all right so now we understand how private works but why is it a good idea to use private methods well one good reason for this is that defining metals variables and classes as private we are declaring an intent that they are not to be used outside the file that they are declared in and this is good to know because when another developer looks at your code they will know which things are meant to be public and which things are meant to be private and also the cleric metals as private has the advantage that they are not accessible by autocomplete outside the file that they are declared in overall as your codebase increases in size it is very beneficial to publicly expose only the variables metals and classes that are meant to be public another way of saying this is that the fact that we have this method called build content over here is just an implementation detail of the sign-in page so while the bit metal has access to it the method is not accessible from outside alright so in summary we have learned to use underscores to declare things as private and we have seen that it is good practice to use private whenever possible okay so we are now ready to continue building our app and we'll carry on on the next video in the previous videos we have seen how to create a vertical layout by using a column as well as a combination of containers and size boxes just as a reminder about what our goal is for this page let me open up the completed time tracker up and here what we have is a title with a number of buttons one thing that you can notice is that the buttons don't extend all the way to the edges of the screen and also there is that some distance between the buttons themselves so the next thing that we are going to do is to get back to our layout and learn how we can add some padding to our widgets so to start off we are going to look again at this container widget over here and we're going to use a new property which is called padding now this padding takes an edge in such geometry object now this is not something that we have seen before so for now I'm just going to type in some code and then I will explain how it works so what we are going to do is to add a padding of 16 points to each side of this container so to do that I can type in edge in sets but all and then passing the value 16 okay so once i hot reload i can see that now that three boxes are inset by 16 points in all directions one thing that i want to show you is the documentation for edge insults so if i tap through and scroll up all the way above the class decoration in here i can read that edge insert is an immutable set of offsets in each of the four cardinal directions so in essence this means that with edge inserts you can control the amount of padding on each of the four dimensions and namely this is left right top and bottom so the matter that we have used a second angle was called edge instance not all and we can see clearly that all it does is to set all these different properties to the same value so throughout this course we will use padding a lot more and so as we go along we will see other ways of using inserts now before we move on let me point out one more thing here we have used a container as the parent of our column and we are slowly starting to learn that container is a very useful widget that is going to help us a lot with our layouts however in this example if we don't care about the background color of this content window but we are only interested in the padding that we have just said we can actually replace our container with a new widget which is called padding now padding doesn't have a color so we had to remove this but instead it takes just one property and that is called padding and it behaves exactly in the same way as the padding that we had in our container so if we have to load the code now we can see that the background now goes back to white but the padding remains the same now padding also takes a child and that is why our code continues to work with the column now becoming the child of the padding widgets okay so we have seen how to use the putty widget to add padding around our content the next thing that we want to see is how we can not padding between our boxes so this is something that is actually very simple because all we have to do is to add the sized box between our container widgets over here so let's try that so here I'm just going to add a size box and I'm going to give it a height of 8 points and if I save I can see that now there is a small padding between the orange and the red widget so just to complete this I'm also going to other sized box here as well with the same height and if I save here it is okay so what I've just done here is a little trick that you'll see me doing again in this course and that is whenever I have widgets that are arranged vertically and I want to add a fixed size padding between them I can do that by simply inserting a size box and using the height property as this facing between the widgets alright so we are making great progress with this layout and we are going to continue on the next video in the previous video we have learned how to use padding sing flatter okay so we will still be able to add more interesting widgets to our layout but before I do that there is one little tweak that I want to do now if we head back to our completed up over here we can see that these widgets are not positioned to the top of our content area but instead they are centered vertically so let's take a look at how we can do that so back to our app we can see that our boxes are arranged to the top of our content area now if you remember when we started talking about columns we have seen how the cross axis alignment property works but there is also another property called main axis alignment and this is what we need to use in this case so if we head back to our column over here we can type in mine axis alignment and give it a value of main axis alignment the center if we reload we can see the our three boxes move down to the center of our content area which is exactly what we want okay so I think we are ready to move on and in the next video we'll add some new interesting widgets okay so I think that these nice colorful boxes over here have kept us good company over the last few videos but regrettably it is now time to say goodbye to them so we're going to slowly replace them with some more interesting widgets and so to start off we're going to add a new widget called text as the name implies text can be used to add text labels to the app and so what we want to do is remove the first orange box and add the new text that says signing so let's delete this container and add a new text instead now the text that we want to show will say sign-in and if we save and reload we can see the yeah the text appears it is slightly small and it is on the left over here so what we want to change now is the horizontal positioning on the text as well as its size so let's take care of that so for the alignment there is a property which is called text align and that is text align and we can set it to Center if we reload we can see that now the text is centered in the middle which is what we want now in order to change the size of the text we need to use a property which is called style so if I type that in it takes an object which is of type text style and textile is something that has a number of different properties so for now we are interested in the font size and we can set this to something big for example 32 like this and if we say we can see that the text is definitely become bigger and I would also like the font weight to be a little bit bolder so to do that I can use a property which is called font weight and I can set it to font weight dot bold for example and as we can see the thickness of the text has now increased I find that this may be still a little bit too thick for my taste so I'm going to tap through font weight and just look at the documentation and it says that it the thickness of the grease using to draw the text and it also shows me a set of values that go from 100 all the way to 900 and these are what we can use to have more fine-grained control over how thick we want the text to be so bold is actually defined to be weighed 700 and maybe in my case I want something more like semi bold so that is weight 600 so I'm going to choose this and if I go back to my page I'm going to pass that in and when I save I can see that the thickness are slightly reduced okay so this looks good one thing that I want to say is that text style has a number of interesting properties that you can use to tweak the way text we just look in your app so if you want you can pause the video and spend some time learning more about textile and all its properties alright so I'm happy with this text and we can continue on the next video in the previous video we have added some text to our signing page and now we are ready to make things more interesting so in a minute we are going to add a bottle to our page but before I type in any code maybe I can just clarify what is a button and there are three main things that you need to know a button is a widget the user can interact with the button by tapping on it and when the button is pressed we can be notified with a callback now a callback is simply a method that is called for us and we can use it to perform some action so to give you some context let me just open the complete up which is over here so as we can see there are a number of buttons and what happens for example when I tap on the signing with Google button is that I get this pop-up and here I could continue with the signing process so the way this flow works is that this button is part of the widget tree for the signing page and when it is pressed I use a callback to execute some code that performs authentication with Google signing now that I explain this let me clarify what the next steps are so for the remainder of this chapter we will see how we can add buttons to this page and we'll spend some time customizing them so that they look exactly as you see over here so our next goal is to get familiar with buttons in flutter and complete the UI for our signing page after we're done with all of this we'll take a look at how to use the buttons code box to hook up the authentication functionality for our app so let's up the first button in our next video we are now ready to add a button to our signing page and as a first step we can remove these two boxes that have kept us company in the last few videos so I'm going to my code and down here I'm going to remove these two container boxes and reload so now we are left with just a signing text now the battle that we are going to add is called raise button so let's try to add it and hot reload so I'm going to add our raise button and just see what happens so as we can see there is a great rectangle that appears on the screen now that is progress but it's not very interesting so let's add some properties to our button the first thing that we're going to do is to add a text widget as the child of our button so if I type in child I can specify a text and as the text I'm going to say sign in with Google so if I add this and reload well I can see that there is some text in here but as it stands we have a dark gray text on a light grey background and it's not very readable so for now what I want to focus on is the background color and the color that you see over here is the color that is used when the button is disabled so what we have done here so far is to add a button but this is disabled and what I mean by disabled is that when the user taps on it nothing happens now the reason that this button is disabled is that we have not specified a code block for when the button is pressed so at this stage I should really take some time to explain how buttons and code box work so here is what we are going to do next I'm going to type in some code and that we are going to observe how the button changes in our simulator don't worry if you don't understand this right away I'll break it down step by step but for now please just bear with me and I will explain later so here I'm going to provide an pressed coal back and I do this by typing in open and close brackets and then open and close curly brackets if I thought reload now I can see that the button has changed color and also you can tap on it and you get this nice splash effect which is a visual hint from material design that tells me that this is a button that I can interact with so while I'm here I want to show you that by adding this on pressed code back I can actually detect that the button has been pressed so to do that I can add a print statement and here I could say button pressed like this so I can then open up the console and what happens if I hotter load and try again is that every time I tap the button I got some calls down here okay so we have just managed to implement a callback for our button however it is the first time that we encounter this syntax over here and I haven't really explained properly how these all works so I'm going to do that in the next video in the last video we have added a raised button to our sign-in page and we have seen that the button becomes enabled when we add the on pressed callback at this point it is a good time to explain how callbacks work and how they affect the way buttons behave in flutter so first of all let's stop through the on press callback and let's see what the documentation says so over here we can read call when the button is stopped or otherwise activated and if this is set to no then the button will be disabled so if you remember in the previous video the button was disabled until we added the unpressed code back to our code so one thing that we need to understand with buttons is that the on pressed callback is actually an optional property and what that means is that if we want we can omit the property altogether and also this is exactly the same thing as adding the on pressed property by giving it a value of no so what I mean is that here we could just replace this and put no instead which is completely valid syntax and if we hot reload we can see that the button is disabled again so two things we need to remember here one is that the on pressed callback is optional and the second is that setting it to no is the same thing as not having it at all now the reason for that is the on pressed is a named parameter of raised button and named parameters in dart are always optional and their default value is no so we should now understand why leaving out the on pressed callback or setting it to no is the same thing and why this causes the button to be disabled if you remember we have also seen that when we provide a value to our code back then the button becomes enabled so the way I've done this before is with a syntax which has two pairs of brackets so run brackets and curly brackets like this so how does this work well once again we can look at the documentation and we can see that the type of the unpressed property is void code back so let's step through these as well and see what we get and here we can read that void callback is a type definition also called a type death and it is defined as a function that takes no parameters and returns no data which is normally written with type void so in order to supply the unpressed go back to our race button we had to give it a method that takes no parameter and returns no data now one way that we could do that for example down here could be to type in a new method called void sign-in with Google write and give it no parameters and I could actually pass this to the own pressed code back on my button over here and the compiler will be happy with this in practice this is often what we want to do and in fact later on we will add the code for authenticating with Google here like this however for now we only wanted to quickly provide a code back so that we can enable our button so the quickest way to do this is just to implement the code back in one line and maybe now this syntax makes a little bit more sense because the first pair of brackets over here defines the parameter list and in our case this should be an empty list and the curly braces here define the implementation which is just an empty implementation okay so for now we're just going to leave this callback like this and we can remove this method because we don't need it yet and we are now ready to continue on the next video we are now ready to get back to our signing page what we want to do next is to style our button by customizing its background color and the text this is quite simple to do and it will give us the opportunity to talk about colors a little bit more in detail so let's get back to our code and we can change the background color of the race button by simply changing its color property so we are going to type in colors and then colors top white just like this and if we hotter load we can see that the buttons color has changed as far as changing the text that we see inside the button we can see that we are using a text widget as the child of the race button so rather than having a number of properties that we can set in our race button to configure text all we do here is to say that the button has a child and that is a text widget now this is a great example of composition because if we wanted it would be easy to replace this text with an image for example okay so let's get back on track because we are already familiar with the text widget we already know how to modify its appearance so to do that we are going to make a little bit of space like this and then here we can understand and this is going to be a text style and we could set here that color for example to be colors black and maybe a font size and we could choose a value of 15 here just reformatting and we can see that our button now has a white background color and a black text okay so I'd like to spend a bit more time talking about colors as you can see here I set the color to black but I think black is a little too strong for my text and I'd like to make it a little bit more light so if I delete this and start typing in black again then I can see that the editor is showing a few variants over here so let me choose like 87 and then I'm going to tap through to reveal the documentation for this so here it will say black with 87% opacity and this is good contrasting color for text in light themes okay so this sounds good because our background color here is white now the reason I wanted to show you this is the flutter defines a number of constant colors that you can choose depending on the situation so especially when it comes to displaying text these different variants of black should work well in most common scenarios so I encourage you to spend some time reading the documentation for the various black colors alright so the next thing that I want to point out is that I would like to have a little bit more contrast between the background on my page here and the color on my button so let's address that in the next video we concluded our previous video saying that we want more contrast between the background color of our page and the color of our signing button so to do that we are going to use a property of our scaffold which is called background color so we're going to add it over here I'm going to say background color and here I'd like to choose a light gray color so the first thing that I could try is to type in colors da-rae now if I hot reload I can see that the resulting value is quite dark and really I'd just like it to be a little bit more white so let's stop through the documentation for gray and see what we get and it looks like gray is defined as a constant variable of type material color so what is a material color exactly so if I tap through to reveal the documentation and scroll up a little bit more here I can see the material color is a class that extends color swatch of type int so a color swatch is something that we can use to define a variety of shades so every time we choose a material color as a color to be used in our UI we can actually choose between multiple shades of that color and that is because a material color is a color swatch so let me just go back to my code and show you what this means in practice so over here I have prepared this code which defines about two different swatches so what I'm going to do is to copy/paste all this code inside the build method of my signing page just like this and what I can see as a result is that Android studio draws some little squares next to each shade for the corners that I have chosen so this is like a preview of all the color shades now this is quite useful and you might remember that we wanted to choose a light gray color for our page so all I have to do is to go down here where I've selected colors of grey and add some square brackets and then I'm going to choose the correct shade for what I want so if I try 200 and hot reload I can see that now I have a much lighter gray color over here okay so we should now understand a little bit better how material color works and I'm going to leave you with a little tip so every time you choose a material color but you want a shade of that color which is lighter or darker than the primary color itself remember that you can easily preview and choose the shade that you want by adding square brackets to your color and choose the desired shade like I've done here all right so let me clean up this code which we don't need and we can continue on the next video in the last videos we started getting familiar with the raised button class and we have seen how we can set our child text widget and also the color over here soon enough we will add more buttons to this page to represent the various sign-in options that will be available on this earth but before we do that I want to discuss one additional property that we can configure to modify the look of our button and that property is called shape now what we want to do is to make our buttons shape look like a rounded rectangle so in flatter this is something that is relatively easy to do so I'm going to go ahead and type some code and then I'll explain it so here I'm going to add a shape property and I'm going to pass it out rounded rectangle border now to this object I'm going to pass out border radius and here I can specify a border radius thought all and the value that I'm going to give it is radius dot circular and then a value of 16 point zero for example okay so with this change I can hot reload and I can see the the border of this button has changed according to the radius that are specified so this is maybe a little bit more code than we were hoping for and the reason for that is that there are multiple shape objects that we could choose from and for this shape if we want we can customize each corner of the rectangle to have a different radius in practice this is not something that you will need very often but I just wanted to spend a little time to talk about shapes so that you know that they exist and how to use them by all means you are free to look up the documentation for all these classes for now I'm just going to change the board already to something smaller like four points and we are going to continue on the next video in the previous video we have added a shape parameter to our raised button and we are almost ready to add some additional buttons to this page so that we can show all the different signing options for the user one thing that we could do at this stage would be to copy/paste all this code and change the text and the colors so that we can show the Facebook sign-in button however we can already see that we have about 15 lines of code to copy paste and then we would have to do this more than once for the remaining buttons instead I propose that we create a custom raised button widget that we can reuse for this and other pages in our application so this is going to be a good exercise about creating our own custom widgets because the intention of this is to create a widget that we will reuse outside the signing page we are going to create a new folder for this so over here in my project panel I can create a new folder and here I'm going to name it a common widgets and then inside this folder I'm going to create a new dart file and I'm going to name it custom raised button like this alright so we are going to add the code for our custom raised button in the next video we are now ready to start implementing our custom raised button so this is going to be a stateless widget so to get this up and running quickly I can type in state less and then I just need to fill in the class name which is custom raised bottom okay I also need to import material from the packages so I can just do that quickly and my code should now compile now inside the build method I need to add the code for building the button itself so what I'm going to do now is to go back to the sign-in page over here and then I'm going to take all this code which I had before and I'm gonna copy it inside the build method of my custom raised button and just to make sure that this works I need to return the raise button so that the build method is happy and I have a widget as a return value now at this stage if I want I can already use this custom raised button inside my sign-in page and to show you that this actually works I'm just going back to the sign-in page and I'm going to add it below the erase button that we already have so I'm just adding our size box of height 8 so that we can have a little bit of space and then I can add in a custom raised button like this of course this is now saved into a different file so I need to remember to import it so I can do that like this automatically now at this stage I can hot reload and I can see that I have two identical buttons the first one is the one that we had created before and the new one is this custom raised button that we have just created now one thing to point out is that this custom raised button is actually not custom at all because all the values are hard-coded inside the bill method so what we want to do instead is supply some configurable properties to this custom widget so that it really becomes reusable so what we are going to do now is to declare all the properties that we want to reuse we are going to add a constructor so that we can ensure that these properties can be set when the widget is created and then we need to remember to actually use these properties on the build method so let's start with step 1 so over here we are going to create a few properties and we are going to make sure that they are all final and this is important because all the properties inside the status widget need to be immutable so final guarantees that the properties are immutable and we can't change them once they are created ok so let's get started so we are going to type in final we just child that the next one is final color color then we have final double and then border-radius and finally we're going to have final void code back on trust now we need to also remember that these properties need to be passed in with the constructor so we're going to create one use the open and close brackets and inside it open and close curly brace brackets so that all the parameters are going to be named parameters and here we can declare them as this dot child this dot color this dot for the radius and this dot on pressed if add a comma I can format the code ok so now that we have defined all these properties we need to use them so in the build method we are going to replace this text widget with the child then this color with the color and then we can apply the border radius over here like this and finally the on press call but can also be updated like this now because we have added this constructor over here we need to remember to pass in all these values to custom race button from the signing page so let's do that okay so in our custom race button over here we need to pass in the properties so we're going to start off with a child and really what we want to do is to use this same text configured in the same way that we had it before so here I'm just going to copy it paste it then we know that we need to pass a color and this is going to be colors the white we know that now we need to pass a border radius and this is going to be 4.0 and finally the own trust code back and we're going to define it in the same way that we've done before like this so now I can actually save and reload and I can see that this all still works but because now this is a reusable button I could very easily change some of these parameters for example by saying signing with Facebook and then if I reload then I can see that this gets updated okay so now that our custom race button is created we can actually delete the old one and we're going to use just this one going forward like this so I'm going to delete that and also restore the text to sign in with Google at this stage you might point out to me that even though we have created a custom range button it still creates quite a few lines of code to just create a button and all we have accomplished with this refactoring is to hide away the complexity for providing a custom shape so what we do now is just supply a border radius as we will see in the coming videos we will create additional custom button widgets that are based on this custom raised button and perhaps the advantages of doing this refactor early on will become more obvious as we make progress in any case we have now learned how to create our own custom widgets and we will see that this is something that will pay off so let's continue on the next video okay so now that we have created our own custom range button class I want to show you a new way of creating custom widgets so what we're going to do next is to create a new widget called signing button and rather than creating this as a stateless widget we are going to subclass directly from custom raised button the goal with this is to make it easier to create a button with the types inside so because the button class that we are about to create will only be used in the sign-in section of the app we are going to create a file for it inside the same folder as the signing page over here so we're going to create a new dart file and we'll call it sign-in button so here is what we are going to do we are going to create a new class called sign-in button and this class is going to extend custom raised button like this I'm going to quickly import the file then this class is not going to define a build method instead we will just create a constructor and passing a number of properties and then we will hand over these properties to the constructor of the super class which is custom raised button so let's go ahead and do that and then I'll show you the advantage of this approach so here we are going to type in sign-in button which is our constructor and then inside we are going to type in some properties the first one is going to be string text then color color then color again but this time text color and then void callback on pressed then what we are going to do next is going to call the super class constructor so the way we do that is to type in a column then super and then Open bracket and inside here we can pass in some parameters so one of them is the child and here we are going to type in text with the text and then style which is a text style and in here we can pass in the remaining parameters that we have created so text color and then for example a font size of 15 now before I go ahead I can see that some symbols are missing so I'm just quickly going to import material from the subtle package so now flutter is happy and then I'm going to continue with my parameter list so next I'm going to pass in the color which is color and then we're going to pass in D on pressed as on press parameter like this and this is done now that I've typed in all the code let me explain it so what we have done here is to provide a constructor as a way to supply all the parameters that are needed to create the custom raised button you can notice that I'm not used the usual list properties syntax that is common with constructors in dart the reason is that this class doesn't declare any properties at all in fact the way this works is by taking all these properties and invoking the constructor of the superclass which happens here then in the constructor arguments of the super class with pass some parameters directly such as the color and the unpressed code block but as you can see we also create a text object on the fly and we configure its text and style properties directly so this is going to make it very easy to use our signing button' class and we're going to see how to do that in the next video in the previous video we have created a sign-in button and now we are ready to use it okay so here what we want to do is replace this custom race button with a sign-in button and to do that I'm just going to change the name so sign-in button the compiler doesn't find this so I need to remember to import it and now the compiler tells us the sign-in button doesn't have a child widget and also it doesn't have a border radius property so let's fix this the first thing that we can do is to remove this child property and instead what we want to do is to type in text and here we can type sign-in with Google also we now specify a text color and this is going to be colors dot black 87 and the border radius is something that we had actually defined for our custom range button but we have not specified that this is a property of our sign-in button so this is why the compiler complains so what we're going to do here is totally remove this property from here and if we wanted we could actually add it over here and maybe hard-coded instead what I'm going to suggest is that we open up the custom raised button class and we add a default value for the border radius so to do that we add a column here and then we specify a default value for example 2.0 now the reason we do this here is that if we ever create a custom raised button and we forget to pass in the border radius then a sensible value will be used okay so I can say here I can see that the radius actually has become a little bit smaller it was for previously now is 2.0 and just to make things clear if I want I can still go to the sign-in button and in here I can specify a border radius and give it a different value for example eight points so at this stage if I say I can see that the new value of eight points has been used so let's revert back to two and let's get back to the signing page and continue in the previous video we have replaced the custom rates button with the signing button that we had created earlier as you can see we can now declare a signing button and it is quite easy to configure it with the properties that we need and if I click through to reveal the sign-in button class then we can see how we use it to configure our custom race button superclass now there is one more thing that I'd like to configure in my custom race button class and that is the height of the button itself in particular I'd like to set the height of all the buttons that we will create on this page 250 points so what we are going to do next is that we modify our custom race button class to add a height property so let's see how we can do that so on the build method over here we create a race button however as you can see this does not take a height parameter so if I try to type in height nothing comes up so the way we are going to approach this is to wrap our race button inside the size box so let me show you how to do this I can move my cursor to raised button and then I'm going to press alt enter and out of the list of options here I can choose wrap with new widget this is a very useful comment because my race button has now been made the child of a widget that I had to specify so here I'm going to type in sized box like this and now I can go and add a height parameter so for now let's add that like this and hard-code a value of 50 points if I hot reload then I can see that the changes take effect so this is great progress the next thing that I want to do is to make sure that this height is configurable so that if other widgets on my code use a custom raised button then they are able to specify a custom height well we have already seen that to do that we can add another property to our us and make it configurable via the constructor just in the same way that we are done here for our border-radius so I'm going to add a new final double-height like this then on the constructor I'm going to call this dot height so that this is a parameter that can be passed in and also I want to provide a default value so in this case is going to be 50 this is so that if the code that kha'zix constructor doesn't specify height then a value of 50 will be chosen and then of course I need to remember to use this height and put it down here like this okay so now that the height can be configured on the custom raised button I could go back to the sign-in button and here I could add it as a property for example with a value of 40 and if I hot reload I could see that the button height updates and if I really wanted to take this further I could also make the height a configurable property of the signing button class itself so that I could specify the height from my signing page but as I said before I want all signing buttons on this page to have the same height so for now I'm just happy to leave the default value that I've sat in custom raised button so in summary it is really up to us to choose what properties are configurable and whether we expose them to our calling code or not alright so we have now completed the customization of our button classes and we can continue on the next video we are now ready to add a new button to sign in with Facebook so let's head back to our sign-in page and down here we are going to first add a new sized box with a height of 8 points and this is as usual to add some spacing and then we can try to add the new sign-in button so just to do this quickly I'm going to copy paste this code and just change its properties so for the text I'm going to have sign in with Facebook then the text color I want to have colors not white and then for the color I'm going to type in a value which should be pretty close to the color of the Facebook logo and so to do this I'm going to use a constructor of the color class which takes an int as a value and this represents the color that we want in hex format so I'm just going to type in a value like this 0x FF 3 3 4 D 9 2 and in case you're not familiar with a hex format you can tap through here and read the documentation alright so for now let's get back to our sign-in page and I just want to quickly point out that I've left the callback value empty in the same way that we have done before so if we hot reload now we can see that the Facebook button appears ok so this looks good and so let's carry on and just to remind ourselves about how our completed page looks like let's get back to our finish up so I can go down here and I can see that there are two more buttons with a text between them all right so let's add those as well I can get back to my main up and here I can have a third button so to do that I'm going to add both the size box and a sign-in button so I'm going to copy paste that and then for the text I'm going to say sign-in with email I'm going to leave the text color as white for the color I'm going to choose colors dot teal which is a variant of green and I'm going to choose a specific shade which is going to be the value 700 and as usual I will leave the callback empty so if I save at this stage you can see that signing with email also appears ok so next I want to add a small text value to separate the first three buttons from the last one that I'll add in a second so as usual I'm going to other size box like this and then here I'm going to type in a text widget this is going to have a value called or and then it's going to have a style and here I can specify text style with a font size for example of 14 and a color of colors the black 87 okay so if I save now I can see that the text appears however is aligned to the left instead I want to specify a text align of text-align:center and if I save now it goes in the position that I want okay so finally we can add the last button to our list and so once again I'm going to copy and paste size box and a sign-in button and in here we can change the text value to say go anonymous like this we want to choose a text color in this case of color stop black and we're going to have a color of line with a shade of 300 just like this so if I say here I can see that the final button appears as well okay so the last thing I want to do on this video is to actually increase the spacing that I have between this title at the top and the remaining buttons so this spacing is defined by this size box between the text and the first button and I want to increase that to 48 so here we go okay so we have made great in building our signing page and there is just one more thing that we need to do before our layout is complete so let's continue on the next video in the last video we have added all the buttons that we wanted to have in our sign-in page and it's been a long way to get to this point but we have learned a lot of things about building the Alton flutter so congratulations to you for making it this far all right so before we conclude this chapter about layouts there is one more thing that I want to add to this signing page so if I head over to the completed app we can see that the Google and Facebook buttons have a little logo to the side of the button text so the final thing that we want to do in this chapter is to see how we can add this logo and in order to do that we are going to learn how to load an image from file in flutter and we will also introduce a new widget that will help us to position our logo in the correct place inside a button okay so in order to proceed we need some images that we will use for our logos so I have prepared a zip file that contains all the images that we need so as a next step I invite you to download this file and then we will resume in the next video where I will show you how to import the images in the project if you follow the instructions in the last video you should enough downloaded a file called images zip so what we're going to do next is to extract this file and I can just double click on it and then we want to take this folder and copy it over to the root of our flatter project so to do that I'm just quickly going to drag this folder all the way up to the root of the project which is at the top and then I can release and Android studio proposes to confirm the folder so this is definitely the root of my project so then I'm going to tap ok and I can see that the images folder appears just below the undried folder so make sure you put it in this place then the next thing that we need to do is to configure our project so that the images can be loaded into the app so in order to do this we are going to look at our project panel down here and open this file called pops back yamo now this is the main configuration file that is generated every time you create a new flutter project so for now we're just going to use this to add new images to the project but as we will see later you can also use this file to add third-party dependencies also known as fluttered plugins okay so let's just stay on track so what we want to do is scroll down a bit and find this section called flutter and we can see that over here there are a lot of comments and this one specifically is about assets so what it says is to add assets to our application add an asset section like this so this is what we're going to do so down here I'm going to press ENTER I want to make sure the time one tab in to follow the correct indentation and then I'm going to type in assets and then a column make sure you have a column otherwise it won't work for your project and then here we need to list the assets that we want to import or project so just to see what the findings are if we open up the images folder over here I can see that there is one called Facebook logo and one called Google logo dot PNG so this is what we want to use we can get back off over here and then we can type enter with a new line and then space - space and then we are going to type in images forward slash Google logo top T and G and then we're going to do the same thing for the Facebook one so I'm going to type in - space images slash Facebook logo dot T and G now just to be completely clear in order for the files to be imported correctly we must specify their position relative to the root of the project so because our files are inside this images folder we must type in images and also let's make sure to use the correct extension for the files as well which in this case is PNG okay so after I've done this I can save the file and if I look up over here there are a few comments that are available so the one I'm interested in is called packages get and if you want you can press this but just to show you you can also do this from the terminal so if I open up a terminal in here I can type in flat turn packages get and this will update all the dependencies including the assets that we have just added alright so we have learned how to import images to our fluttered project and very shortly we'll be able to show them inside our application so let's continue on the next video in the last video we have seen how to import images in the pub Specter llamo file before we continue I want to talk about image variants so if we read over here we can learn that an image asset can refer to one or more resolution specific variants and so we also have a link that we can follow to read more information about it so let's open this up and if you want you can pause the video here and read this page to get a full understanding about image variants for now I'm just going to give you a summary and that is that different devices have different device pixel ratios and in essence a pixel ratio defines the pixel density of the display so to account for the different pixel densities of various devices Flattr gives us a way to specify multiple variants for the images that we use so if we head back to our project you can open up the images folder over here and you'll see that this has 2.0 and 3.0 variants for the images that we use so if you open up the Google logo in 1x + 2 X + 3 X we can see that these are different variants of the same image so what this means is that you can run the app on devices with different pixel densities and flutter will automatically choose the variant that is most optimal for your specific device but in order for this to work you need to specify multiple image variants like I have done here and the naming of these folders actually matters so as I said you can read more about image variants on the documentation and for now let's get back on track and continue on the next video okay so now that we imported the logos into our project we can do a quick experiment to see if we can show them on the screen so what we're going to do in this experiment is to add a new image to this page and we are going to add it just after our last button over here so here we can introduce a new asset called image an image has a number of different constructors and the one that we need to use to load an asset from file is called asset here we need to pass the name of the asset in our case we were going to use images slash Google - logo dot P and G and if we hotter a lot now we can see that this Google image appears on the page okay so this is interesting but ultimately what we want to do is to add the image inside our button to the side of the text over here okay so I think that a first step towards that is to see if we can show this image inside the button and one thing that I want to point out is that this image class is actually a widget and if you remember when we created the custom raised button class we specified that is child property is a widget so the point that I'm trying to drive home here is that if we want we can create a custom raised button and pass an image as a child and we can do this very quickly because all we have to do is to wrap our image asset into a new widget and this is going to be a custom raised button like this next we need to remember that our custom raised button takes a color and a callback so here we can type color and then here we can add colors the white and then the on pressed callback and as usual we can use an empty callback like this so if I save here and hot reload I can see that a new button appears and the image is placed just inside the button okay so while week that I could do at this stage is to take this button and move it just above the Google sign-in button which is up here and maybe add a little bit of spacing as well so as usual scienced box with a height of eight so that I can reload and see how the page updates okay so I think this is a good time to take a pose so that we can highlight what we have just done so we started off by adding an image to our page and then we've wrapped this image inside a custom raised button and I think this really shows the power of composition so perhaps now we understand a little bit better why I have chosen to implement the custom raised button class the way I did so you see I have explicitly decided that the custom raised button constructor should take a child widget and the fact that this is a generic widget and not a text for example means that I can put any widget I want as this child okay so if there is a point that I'd like to drive home here is that building reusable and configurable widgets can be a big win in the long run okay so this is great progress and we are going to continue in the next video in the last video we have seen how we can add an image inside our button our next goal is to figure out how we can show an image and the text side-by-side earlier on we learned that in order to align multiple widgets vertically we can use a column widget so it might be tempting to see if there was a way to align widgets horizontally instead and in flutter this is easily done with the widget called row now one interesting thing that we can try is to wrap our image inside a row so let's try that and here understood yogi's misses an option to wrap with row so now because row doesn't take one child but it takes a list of children instead then we end up with a list with our image as the only child now what we could do next is to add a text widget as the second child and here we could say sign-in with Google so here we could then hit save to hot reload and now we have both our logo and the text inside the button however these widgets are not positioned in the way that we want ideally we would like for the text to be centered and for the logo to appear on the left now previously we have discovered the columns have a main axis alignment property that we can tweak to arrange widgets within the main axis similarly we can specify a main axis alignment property for our row so for example main axis alignment the center and this will affect how the widgets are positioned in the horizontal axis okay so now we can see the effect of main axis alignment dot Center and clearly this is still not what we want what we need to do here is to find a way to add some spacing between the logo and the text widget and it turns out that there are three possible values of main axis alignment that can be used to add spacing between widgets so these are main axis alignment dot space between space around and space evenly so for now let's try space between and see what we get so it seems that now the logo has gone into the correct place however that text itself has been pushed all the way to the right okay so I think this might be a good time to look up the documentation for main axis alignment and specifically space between and see if that gives us a clue about what we can do to fix our layout so if we tap through we can see the space between is used to place the free space evenly between the children now this is useful however at the moment we only have two children inside our row and as a result all the available space is going to be in the middle between the logo and our text widget okay so what I'm going to do next is to suggest a little trick that we can use to take advantage of the behavior of space between so that we can get our text position right in the middle okay so here is what I'm going to do I'm going to copy this image asset and I'm going to paste it right after the text widget if I save it then I can see that what we end up with is a word logo than our text and then the logo again left to right so by using space between we can ensure that the spacing between widgets is the same and because the first and the last widget are identical images then they have the same width so as a result the text appears exactly in the middle okay so with this little hack of adding another image asset to the right of our text we have managed to get the text in the desired position somehow if there was a way to hide the image to the right but without actually removing it from the row it self then the positioning would remain the same and our button would look as standard so we are going to see how to do this in the next video in the last video we have learned about the RO widget and explored various options for aligning with just horizontally we have also been able to Center our text widget horizontally now the next thing that we want to do is to see how we can hide the image asset on the right without removing it from our row now this is a good opportunity to introduce a new widget called opacity so I'm going to add this widget first and then I'm going to explain how it works so here like we've done before we are going to wrap our widget with a new widget and we are going to call this opacity we're going to format my code now opacity takes a child which is our image asset and also it takes on opacity decimal value between 0 and 1 and so here we're going to set this value to 1 and see what happens and if we ha to a load we see that the image is still here however if we set this value to 0 and save we can see that the image disappears so how does this work let's stop through the documentation for the opacity widget and if we scroll all the way up we can discover the opacity is a widget that makes this child partially transparent so the way this works is that if we set a value of 1 then the child widget is completely opaque and visible whereas if we set the value to zero then the child widget is completely transparent in other words we can use the opacity to make widgets visible or invisible but without removing them from the widget tree and this is exactly what we want because it means that we can take advantage of the main axis alignment top space between property of our row to Center the text horizontally okay so we have managed to get both the logo and the text in the desired position inside our custom raised button and we've done that by using a row the main axis alignment value of space between and an opacity of widget just to be clear I admit that this is a bit of a hack but considering that we are only using this to build a relatively simple layout I think it works well in this case so what we are going to do next is to refactor this code into a new widget class so that we will be able to reuse this for the Facebook button as well in the last video we have completed the layout for our Google social signing button what we want to do next is to the factor this code into a new widget class that we will be able to reuse this widget class will be configurable and we will be able to specify an image assets name as well as the text that we want to show so in the same folder as our sign-in page we are going to create a new dart file and we'll call this social sign-in button then we need to decide how we are going to implement this in the previous videos we have seen a couple of different approaches for how we can implement custom widgets initially we created this custom raised button class and the way we have done this was to subclass from stateless widget and then implement the build method with the logic that we needed and this works by using the properties that are passed into the constructor later on we created a signing button class and in this instance we went for a different approach and that was to subclass directly from our custom raise button class and passing any constructor arguments directly into the constructor of the superclass this has the advantage that we don't need to declare a build method at all and so this approach requires less code so I'm going to suggest that we use this approach once again and the way we are going to do this is to copy paste this whole file into our new social sign-in button file as a first step we're then going to rename this as social signing button and rename the constructor as well so what we have now is a new widget class called social sign-in button but it's implementation is identical to that of sign-in button what we want to do instead is to replace this text widget with the new code that we have added on signing page to show a logo and the text inside the button so in other words we are going to copy this row widget and its entire content and we are going to paste it in here to replace the text widget okay this is good progress however we can see that the asset name and the text are hard-coded instead we want these properties to be customizable so what we are going to do now is to add a new property to the constructor called string asset name and then we are going to use this property over here and also over here and also we want to use the text property that is passed to our constructor inside this text widget finally we have this text color that is passed over constructor but is not used anywhere so if you remember the way that we use this is to add a style property to our text and so here we are going to type in style and then it's going to be a text style with a color of text color and we also specify a font size of 15 which is the same value that we were using in our signing button okay so this completes the implementation of our social signing button class and what we want to do now is to use it so if we head back to our signing page class what we are going to do is to replace this signing button widget with our new social sign-in button we must of course remember to import it so let's do that and we must remember that this new class requires a new parameter called asset name so we are going to add it and here we can type in images / Google - logo dot PNG so at this stage we can save the file and we can see that the second Google sign-in button now shows the logo we want okay so we now no longer need this custom raised button class that we had originally used to prototype our social signing button and you can see that the new class that we have created is much easier to use and requires much less code and that's because we've hidden all the implementation details about the row layout so let's delete this widget alongside the spacing and refresh okay so it looks like I originally had a spacing of 48 points between the title and the first button so let's restore that and now we are ready to add the logo to the Facebook button as well so down here we are going to transform this widget into a social signing button as well and we are going to type in the asset name which is images slash face book logo dot P and G and we can refresh again and we can see that the Facebook logo now appears okay with this last change we have completed the entire layout for the signing page so congratulations for making it this far I feel that this has been a long introduction to building layouts in Futter but we have learned a hell of a lot in the process before we complete this chapter and move on to the next one there is one more detail that I want to illustrate and we are going to see that in the next video in the previous videos we have created three custom button widget classes that made it easier to write the layout of our signing page in particular this social sign-in button takes two properties called asset name and text and these properties are required so that the widget knows how to draw itself I want to quickly show you what happens if we forget to specify one of these properties so I'm going to comment this out and save and here I can see that the screen goes completely red with an error in yellow additionally I could open up the console and if I scroll up I see a long stuck trace which shows an error as well in general this is something that happens when we forget to pass the required properties to one of our widget and so if we look at the assertion over here it is not entirely clear but this is a set name not null is not true and the reason we get this assertion is that the emails the asset constructor that we pass over here really needs to have an asset name that is not null so in general this is an error that happens when we forget to pass required properties to one of our widgets and because we have commented out this line and asset name is a named parameter then this will take a new value if we don't specify one so this is not a great situation because we get an error at runtime it would be a lot nicer if the compiler could help us out here by letting us know that asset name really is a required property this will be very useful and fortunately in dart there is a way to specify when name parameters such as asset name are required so let me show you what I'm talking about when we declare name parameters such as this awesome name over here we can use a special annotation called add required and this tells the compiler that they are actually required so if I move back to the sign-in page I can now see that if I over to this social sign-in button it tells me the parameter a set name is required and this is flagged up as a warning even on the right over here so the required annotation is useful because it can inform the compiler about which parameters are needed and this helps us as developers because if we ever forget to provide a parameter that is required then we can get a warning and this is very useful because it allows us to find any potential programming errors early so let's restore the asset name and we can see that the warning goes away and let's save and reload as well ok so with this knowledge I think it could be worth to reveal the custom classes that we have created and make sure that we have the required annotation where necessary so if we start with the social signing button we can take a look here and shoot the text string have a required annotation well the answer is yes because if this is no over here then the text widget will throw an error so we're going to add required in here as well and what about the other parameters well the color and the text color are optional and the unpressed callback is also optional in fact we have learned early on that we can pass a new callback intentionally to disable the button so we can head over to our signing button' class and this one takes similar parameters so the only one that is required is the text string and finally we can take a look at the custom raised button class so here the first property is the child and this is passed down to the race button widget over here now this is actually not required because we could have a race button without a child then we have color and contrast which as discussed are optional and finally we have the border radius and the height parameters now because we have provided default values for these parameters it doesn't make sense for them to be required because when we don't specify these parameters then the default values will be used okay so we have reviewed all our widgets and added the required annotation where appropriate next I'd like to give you some guidelines about when to use default parameters and when to use the required annotation and I'm going to do this in the next video in the last few videos we have completed the design of our signing page and in the process of doing this we have created our own custom widgets and the way we have done that was to first write some code in the signing page and then extract this into separate widget classes the reason for this is so that we can have some reusable code and making code reusable is often a good idea because it means that we don't have to reinvent the wheel over and over and since building reusable widgets is useful on this video I want to share a couple of guidelines that you can follow when you create your own widgets in particular I'm going to talk about three different things default parameters the required annotation and assert statements we have already seen default parameters and the required annotation however we have not yet talked about assertions and this is a good time to introduce them as they are often used together with the required annotation so let's take a look at the signing page that we have created and we can see that all the signing buttons that we have in here use a text property as we have seen if we forget to specify the text property so for example like this then we get a warning from a compiler telling us that the property is required now this is because we have declared this text property with our required annotation however if we wanted here we could simply pass in a text value of null and the compiler no longer complains about this and that's because all require does is to check if we have added the property or not what it does not do is to check if that property is no or not so if we hot reload we get an error that comes from text art inside the flutter SDK and it tells us there has been a failed assertion with data not equal to null and if we open up the console we can see the stack trace for days now if we wanted we could tap through and this will reveal a line inside the flutter SDK and this has an assert statement in it so this is an assertion which is a special statement that we can use at run time to check whether our condition is true or not and if that condition is not true then we get an error like like the one that you can see over here so if you want you can spend some time looking at the source code for various widgets in the flutter SDK and you will find that many of them have assertions and these are used specifically to guard against programming errors at runtime so what I'm going to suggest is that we should also use assertions in our code as a way to catch errors early and let me show you what I mean by that so if we go to the social sign-in button class that we are created here we could move the super line one line down and here we could type assert for example text not equal to null with a comma and if I reload now I can observe that the error points exactly at my own source code inside social sign-in button and this is a good thing because it is often much easier to diagnose errors like this happening in your own code rather than in the flutter SDK so now that we have seen how asserts are used maybe it's a good time to repeat again what is the difference between requires and assert required specifies a property must be included and assert stops execution if a boolean condition is false so there are some cases where if you want to make your code robust you might need to use both and this is exactly what we want to do here so just as we added an assertion to our text property we can also add one for our asset name property so here going to add another line called assert and then of that name not know and this is needed because if we pass it an asset name which is know then flutter wouldn't know what asset to load for our image okay so we have other assertions to our social signing button class and similarly if we open this signing button class we can also add an assert for our text property over here so let's do that with assert text no no and this is all we need in terms of checking assertions for our sign-in button and our social sign-in button so if we go back to the sign in page we can now restore the text that we're adding here and we are good again okay so before we move on I think we should take a look at our custom raised button class as well if you remember we have said that sometimes it's useful to provide default values for certain properties in this case we have default values for border radius and height and what this means is that when we create a custom raised button we don't have to specify these values explicitly and all of these can be very useful so as you can see here I could change the value to 60 for example and the border radius to 8 and if I hot reload then I can see that all the buttons on the sign-in page are updated so default values provide sensible defaults for properties in our widgets okay so let me just put this back and carry on so what default values don't do though is they don't prevent us from using the properties incorrectly and what do I mean by that so let me show you an example if I open up the sign-in button class again we can see that we are calling the super constructor and passing in the child the color and the contrast properties however if I wanted to be a little bit malicious here I could add a border ready and give it a value of no and nothing stops me from doing de because in dart we can set any variable to know if we want to so if I save now I'm going to get an exception now and this is going to have a fairly long stuck trace and if I take a look at it I can see that all the lines in this stack trace refer to code in the flutter SDK so unless you are familiar with the flat tire SDK source code it is really not clear what is going on and diagnostic errors like this can be quite difficult however we have just learned that we can use assertions to add runtime checks to our code so if we open up the custom raise button class we can go to the end of our constructor here and add a column and then assert border-radius not know and if I save and hot reload now I can see that the error has completely changed and it is a lot clearer now because I can see exactly the code that has generated the error right in my source code rather than on the flatter SDK so the stack trace that I get now is much more useful and all of this is because I have added an assertion in my code so the point that I'm trying to drive home here is that assertions are very useful runtime checks that you can add to your code and especially when you write reusable widgets it can be quite valuable to have assertions so that any errors are caught early if the widgets are used incorrectly so let me fix my code so that it works again so here on the sign-in button I'm just going to remove the border radius and reload and we're all good and we can do a quick summary so we have seen how to use default parameters the required annotation and runtime assertions to make our code better the last thing that I want to point out is that assertions only work in the back mode they are completely removed by the compiler when you build and run your apps in release mode and this is something that makes sense because really assertions are there to surface programming errors so we should always be able to fix these types of errors before our code is ready for production okay so this concludes this section about building layout in flutter of course my complete flutter and firebase course covers many other topics that are essential if you want to build robust and maintainable apps that can run in production nearly 5000 students have enrolled in this course and have rated it very highly so if you're serious about learning flutter and firebase you should consider enrolling as well once again you can buy the course for a discounted price on my website at code Villandry dot-com or using the link in the description below thank you very much for watching if you enjoyed this video please like and subscribe and I'll see you on the next one
Info
Channel: Code With Andrea
Views: 24,479
Rating: undefined out of 5
Keywords: flutter, dart, android, ios, mobile app development, programming, tutorial, course, udemy, coding, firebase, layouts
Id: bdam6VY0Db0
Channel Id: undefined
Length: 129min 52sec (7792 seconds)
Published: Tue Jun 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.