Flutter - Awesome Paint App Using Custom Paint | Flutter Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey hello friends and welcome to retro portal studio and in today's video we are going to be taking a look at creating this awesome paint app in flutter so this is an app with a simple layout it has a drawing area and a simple panel below in which you can change the color adjust the stroke and also clear the panel above so what you can do here is you can draw anything in the paint area and if you want to change the color of the pencil that you're using you can just select the color from this dialog and close and the color of the pencil has changed you can also change the width of the pencil or brush by increasing or decreasing this slider and if I make this fault then you can see that the stroke width is changed and also if you have drawn something wrong you can just click on this button and clear the whole drawing panel so this is a simple app that we'll be focusing on in this tutorial and in this tutorial we'll be taking a special look at custom painter which is used to create such apps where you want the user to draw on the screen or something like that so let's get started okay so right now I'm in a simple flutter app which is having this my app widget which contains a material app and this material app is having a home screen of my home page so this my home page is a stateful widget which contains a scaffold which further contains a stack as the body and a container so the reason for having a stack as the body of the scaffold is just to have this background gradient in the scaffold and this gradient comes from the container which is the first child of the stack widget and this container is having a decoration which is a box decoration which is further having a gradient of type a linear gradient and these colors are giving the gradient that you can see on the screen so other than the code here have added a dependency in the pub spec dot yellow file that is this flutter color picker that is at version point 3.2 so what this dependency helps us do is it helps us to create such dialogues in which you can just select the color and you can see that this one was in the that I showed you earlier and you can create any dialogue that you want and we'll be adding this simple code in our application to create the dialogues from this dependency so this is the simple app that I have right now and we'll be creating the complete painter from this app here so let's get started okay so first things first is we have to create a layout in which we can have a paint area above and a simple layout to contain these three elements below so for that we'll be adding a simple column after the container so in this we'll be having a column and in this will be having children property and for the children property we'll be adding a simple container to have this drawing area above here so in this container you can see that we have a simple shadow here and for the shadow we'll be adding the simple decoration to this container for the decoration what we can do is we can add decoration for this we can add a box decoration and this box decoration what I'll be having is a border radius to add some radius to it so for the border radius I'll be having radius circular and for that I'll be adding 20.0 and also box shadow so this box shadow requires a list of box shadows so for that I'll be adding a simple box shadow with a color of colors black dot with opacity that is going to be off points for I guess and other than this color this will take a blood radius and for that I'll be adding point five point zero and a spread radius of one point zero so this will just add some radius and the shadow to the container and also for this container we want to have some width and height so for that width and height I'll just be creating two variables here that is going to be of width and height and what I can do here is I can add 80% of width and height to this container that means we can add a width width into point 80 and a height that will be height into point 80 and this width and height is coming from these two variables here which are taking the width and height of the screen using the media query property off context at size dot width and the respective height so if I run the app right now and I bring up the emulator you can see that we have a simple shadow here and there's no color here so the reason we don't have any color in this container is because we have not added one and we only have the shadow here and one other thing that we notice here is we need to have the container in the center of the screen so for that what I can do is I can add two properties to the column that is going to be main access alignment and that is going to be main axis alignment Center and across axis alignment that can be cross access alignment cross axis alignment dot Center and if I run the app right now so you can see that the container comes here in the center and what we can also do is we can wrap this column with a center widget to Center the whole column so I run the app right now and you can see that the container comes in the center of the application area so other than this container here we also want to add a second child to this column okay so for the second child what I'll be doing is I'll be adding another container so this container will contain three buttons sorry two buttons and one slider that is this one two buns and one slider so for that we want to have a row so that we can have these elements horizontally aligned so for that what I'll be doing is I'll be adding a width to this container that is going to be same that is width into point 80 and a child so this child will be of a row and in this row we'll be adding the three elements that is using the children property okay so in this drawer what we need to add is we need to add a simple icon button and another icon button and a slider in between so what we can do is we can create a simple icon button here that is an icon button icon button and the first property is requires is an icon that'll be an icon and it requires an icons dot I guess color lens and the other property is for the unpressed which I'll be keeping empty for now and let me just copy this icon button and create another one so for this second icon button we need this icon here so I guess this is the layers something yeah layers clear and we can have this second one okay so other than these two icon buttons we'll be adding another slider in between them but we'll add that later on so if I run the app right now you can see that we have these two icons here but we don't have any background like we have in our original application so for that what we need to do is we need to add some properties to the container so in this container what we need to add we need to add a decoration so this will be up type box decoration again and in this we can pass a color so that'll be off colors dots white and a Bordeaux radius like we did above and for the border radius I'll be adding all various circular that will be 20.0 and I think this will do the job and if I run the app right now you can see that we have the container with two buttons in it and we don't have at the slider right now because we'll be adding that later on once we have the paint area working so the next thing that we can do is we can add some space between this paint area and this bottom layout by adding a simple sized box in between two containers so this sized box will be having a simple height let me just keep it at 10 and by adding this sized box you can add a simple empty space in between these two layouts and if you want to add some more space what you can do is increase the height of this sized box and run the app again and this will update in the layout okay let's come now to the core of the application so what we need to do is we need to detect the user's touch on the screen so basically we need to detect three events that is when the user presses on the screen when the user moves the finger on the screen and when the user lifts up the finger so for that what we can do is we can add a simple gesture detector so the police for adding the gesturedetector is this container so we can get the localized parameters for the users click so what we can do here is we can add a child property to this container and then this child will be having a gesture detector so gesture detector is another widget given to you by flutter itself so it helps us detect the user's gestures on the screen like tap long press or many other gestures the ones which we'll be interested in in this tutorial will be on pen down on pan update and on pan and so these will be the 3d gestures that we'll be interested in in our application and these will contain three functions so on pen down we'll get the details of on pan down on pan update will get the details of on pan update details of on pan update and on pan end will get the details of on pan ends so these three events will help us detect when the user clicks on the screen when the user moves the finger and when the user picks up the finger and leaves the screen so we need to use these three parameters of the gesture detector okay so other than these three properties we also need to add a child to the gesture detector on which it needs to detect the click events so for the child will be having a custom paint widget so this custom paint widget is really a powerful widget given to you before SDK and it helps you to draw anything on the canvas that gives you so we'll be adding the custom paint as a child of the gesture detector what we want to do is we want to detect the users click and we need to draw the same thing in the custom painter so what this custom painter requires is a painter property which takes a custom painter so for this custom painter what we need to do is we need to create our own class that'll be let's just name this my custom painter and this will extend the custom painter class itself not the custom paint the custom painter and we also need to add the override method here okay so extending this custom painter gives our class two overrides that is this paint and should repaint so our most of the work will be in this paint function and for now what I'll do is I'll just go up here in the painter and I'll just add my custom painter so what we need to do is we need to implement this paint function here so that we so that the user can paint on this screen so if I run the app right now and I go to the emulator what you can see is we have an exception here so this says boolean expression must not be null so the reason for having this exception is that we have this should repaint function and it should return a boolean but we're returning a null here so what we can do is we can change this null to true and if I run the app again you can see that there exception is gone and we have a simple container here so the reason for having nothing in the container although we have added this gesture detector and a custom paint is because we don't have anything to paint on so basically this custom paint does not contain anything and what we need to do is we need to add a background to this custom paint so that we can draw on that background and we want that background to be of the white color so basically what we need to do is we need to come down to this my custom painter class and in this you can see we have a paint function which gives you a canvas and the size so a canvas is basically the area on which we need to paint and the size is the size of the area so basically what we can do here is we can create a paint object so this paint is basically something like a brush and you can add color stroke and all this property to this paint object so what I'll do is I'll just create I'll just name this paint object as background and I'll just initiate it with a new paint object and give it a few properties like color that will be equal to color start white because we want the background of the canvas to be white in color so other than this paint object what we need to do is we need to create a rat which will be a rectangle area in which we want to paint the white color so what we'll do is I'll just name this rect and I'll just use the constructor of this rect class that is from LT WH that means left top width and height so using this function here what we need to do is we need to give it a left of zero at top of zero and a width of size dot width and a height of size dot height and this concludes the area on which we want to paint the white color so what we can do right now is we can use the canvas and we can use its function of draw rect so basically this function takes a rect and a paint object so this function will paint this color on this rectangle area so for this paint I'll just add a background color and I'll just add a semicolon and for the rect I just rename this to rect and add this to the canvas and if I run the app right now what we can see is we can see that there is a white background in the canvas and the other thing that we need to do is we need to round the corners of this canvas so basically we need to round the corners of this custom paint so for that what we can do is we can wrap this custom paint with a clip our rekt so and in this clip or rect we can add a border radius so I have mistyped this two clip erects we need to add a clip our erect so we can add a border release here and in this border radius we need to add a radius not circular of 20.0 and if I run the app right now and you can see that the corners of this custom paint are rounded off by the radius of 20 point zero so basically we have the layout ready we only have that slider missing but we'll add that at the end so basically we have this canvas and a simple layout in which we have the buttons and the upcoming slider so coming to the next big thing is we need to detect the user's gestures on the screen and we need to paint something on this canvas so let's start with that okay so the very first thing that we a check is how to draw anything on this canvas so basically this canvas gives you a lot of functions to draw things on the canvas so this draw rect we have already used this draw points and draw lines function we're going to be using in our application so what this draw line function takes is an offset of 0.1 and an offset of 0.2 and in between that points its it draws a line using the paint object so other than that we have this draw points function which we'll also use in our application to draw points on the screen it also takes a list of offsets so the first thing that we need to do is we need to get these offsets and for that what we need to do is we need to detect the gesture of the user on the screen so let's take a look at that now so for detecting the gesture what we need to do is we need to come up to this gesture detector and we need to use these three functions that is the on pan down on pan update and on pan end that are respective to the user tapping on the screen the user moving the finger on the screen and the user lifting the finger up from the screen so these three functions will help us in getting the location that is the offset on which the user points the finger on the screen and what we also need to do is we need to collect those offsets in a list of offsets so for that let me just go up on the state here and let's just create a new list that is off the offset and just name this points and let's just keep it empty for the starting and what we need to do right now is we need to come down to this on pan down and we need to update the state so what we can do is we can call this dot set state so what we need to do in this set state function is we need to add the offset to the points and we can get the offset from these details right here we can get the local position and make sure you don't get the global position we only need to get the local position that is local to the widget on which we're drawing so we need to copy the same and we need to copy that to the on pan update and in the on pan and we'll just add null in place of this local position here so what we're doing here is we're getting the local position of users finger on the screen according to that widget that is the container here and we're adding that to the points in the form of an offset okay so we're doing the same thing in the on pen update and we're adding null in the on pen end so that we can detect that the user has lifted up the finger from the screen so we can pass these points to the my custom paint and for that we can come down to this my custom paint and create a property here that is the offset and let's just name this points also points and what we can do is we can create a constructor here that is my custom painter my custom painter and this takes a property of the start points and what this will do is we can come up here in the my custom paint and add the points property and pass at the points so basically whenever the user clicks on the screen this just gesturedetector will take the points and add that to the points list and then give that points list to the my custom painter and what we need to do is we need to draw that point on the screen right now so let me just come down to the paint function right here and what we can do is we can use a simple for loop to loop through all the points so let me just write a loop here and this we can say X is equal to 0 and X is less than points a length and let me just keep it -1 to detect the last point and we can add X plus plus so the reason why I added this minus 1 here we need to check if we need to draw a line or a point on the screen because there can be a scenario in which user just clicks on the screen and we need to draw a point there and when the user drags on the screen we need to draw a line there so for that what we need to do is we need to check whether the next point we don't need to check the X 0 we need to check if X plus 1 is not null that means there is another point on the screen so let me just write the code right now what we can see is we can check if point X is not equal to null that means the current point is not null and points X plus 1 is also not equal to null so in this case what we need to do is we need to use canvas dot draw line and we need to give it points X and points X plus 1 and for the paint object what we can do is we can create a new paint object here and we can just name this paint for now paint is equal to paint let me just name this paint and we can add property to this paint like color let me just put the color to be color black and paint dot stroke width that is the width of the line we can give this with off let's say 2.0 and paint dot is anti-aliasing to make the line a bit sharper and we can give this a property of true and what we can also do is okay I'm just putting commas here I need to put semicolons so the other property that we can add is paint stroke cap that is that represents the end of the line whether it should be sharp or it should be round so we can add a stroke cap dot round and we can use this same paint object here and just draw a semicolon here so what we need to do is we also need to detect if the user just taps on the screen in that case we have to draw only the point so for that we need to do is we need to put an else statement here else if the points X is not equal to null not equal to null and the next point is no that means points X plus one is equal to null that means there is no next point so in this case we only need to draw a point so we can do canvas dot draw points and we need to pass a point mode that is going to be point mode dot points and we need only need to draw a single point that is the X so in this case what we can do is we can pass a list of points that contains only one point that is points bracket X and we also pass the paint object here so let me just put in the semicolon here and if I just run the app right now we can see what happens okay so you can see that I can draw anything on the screen right now and there is nothing outside the bounds of the canvas so this is working really good and to make sure you only add local position here because if you add global position let me just replace this local position with a global position and if I run the app right now and I draw anything on the screen there is a nice offset here you can see that the mouse is not at the position on which the canvas is drawing so basically the canvas is getting the global position for the whole screen in place of getting the local position that is local to this widget here so we need to change this global position to local position and hence we get the local position only and if I run the app you can see that we can draw anything on the screen okay so the code that we are written right now is working pretty fine we get the points from the gesture detector and we add those points to the points list that is in the state of my home page and we give those points to the my custom painter which then draws those points on the screen using this paint object here which is a color black so this code right here is having a major drawback that is we can't really change the color of the brush while drawing on the screen so to make you understand that drawback we need to add functionality to these buttons down here okay so for adding functionality to these two buttons down here and also to add that Slyder we need to create two properties that is the color and the stroke width so basically I'll be adding those properties to the state of the my home page so I'll be adding this color and name it selected color and let's just keep this empty and also a simple double that'll be off the stroke width stroke oke width and we also need to initialize those two and at the in estate function that is given to you by this stateful widget so in this in its state what we need to do is we need to give default values to this selected color that is going to be colors dot black and the stroke width is going to be let me just tell this to be two point zero and for changing the color we need to use this package here that is the flutter color picker that we just add it to the pub spec ml also so for that I'll be just pasting a simple function here so basically this select color function what it does is it creates a show dialog that creates a dialogue on the screen and their picker that I'm using right now is the block picker and in the default app that they have here in the color picker documentation is using this color picker we don't want to use that it's basically one of these it's I think this one and what I'm using right now right now is this select and color which shows these around buttons with different colors in it I think this is more elegant so I'll be using this one here and it's called block picker so basically I'm gonna be using this block picker to pick the color so what we have to do is we have to provide picked color that is the selected color and we have to implement that on color change function which gives it a new color and we need to set that to the selected color using these set state function so this is quite a simple function and you can just copy paste that into your code also so what we can do right now is we can come down to this icon button and we can implement the on pressed function and in this we can show the select-color dialogue yeah we can call this select color function and if I run the app right now and go to the emulator and I click on this button you can see that we have this simple tile here which helps us to choose the color also and right now we don't have any way to just check if the color really changed we can change that by adding the color to this icon and we can do is pass in the color property and fasten the selected color and if I run the app right now and I go to the app and I open the dialog and select on the color you can see that the colour of this icon also changed that means the Select color function is working properly and what we also need to do is we also need to add functionality to this button right here which is used to clear the canvas so the functionality of this function is going to be quite simple what we need to do is we need to set the state and we need to empty the list of points that is just by doing points that clear and by doing that let me just run the app again and let me just draw something on the screen and click on this button and you can see that the canvas becomes empty and also what we need to do now is we need to add a simple slider to change the stroke of the brush so to implement the slider what we need to do is we need to add expand to take up the remaining space in the row and in the child of the expanded what we need to add is a slider so a slider takes two values that is a simple value and unchanged function we also need to add some other properties to this slider so let me just add a minimum property that is going to be the minimum value of the slider and also maximum property so I'm going to keep this at 10.0 that's going to be much greater I want to add 7.0 and we can add a simple active color that is going to be the color of the slider itself that is going to change with the color of the brush so we're gonna give it a selected color and we also need to give this value here that is going to be stroke with that we just created in the state of the my home page and in the unchanged function it's going to give us a new value and we need to add that to the stroke width that is we can call this dot set state and in the set state what we can do is we can give the stroke width this new value so basically if I run the app right now you can see that we have a simple slider right here and when I click on this button and select the color the color of the slider also changes and right now we don't have any way to implement this slider into the stroke width also but we'll do that later on so if I click on this button right here the canvas becomes empty so what we need to do right now is we need to pass this color and the stroke property to this my custom painter here and let me just show you the wrong way first so that you don't end up doing that so what for that what we can do is we can just add a simple property here that is going to be color and just name this color and we can add a double that is the stroke wet clear and we can just pass on these two properties to this custom painter also we can just pass in the start color and the start stroke width and we can implement those properties by giving the value to the my custom painter and we can pass in the color that is the selected color and also the stroke width that is going to be the stroke width so after adding these two properties what we can do is we can come down here so instead of this black what we can do is instead of this color of black we can pass in the color and instead of this stroke width the default width we can pass in this stroke width and this is completely wrong way and it will work but it's not the efficient approach and if I run the app right now you can see if I can draw on the screen and if I change the stroke you can see that the stroke of the drawing changes and if I change the color also the color of the complete painting changes and we can't really do much about it so what we need to do is we need to associate a paint object which with each point that we draw on the screen so basically what we need to do is we need to have this paint for each offset that we have on the screen so for that what we need to do is we need to create a new class so for that what I will do is I'll just come up here above this my home page and in here I can just create a new class that is the drawing area so instead of having an offset here we need to have a drawing area so basically you can name this anything I have just named this according to just my own thing so basically this drawing area has an offset and a paint so what happens is we have a separate paint object for each of the offset in the list so whenever we change the color or change the stroke we don't reset the points that we have previously drawn on the screen so for that what we can do is we can change this offset to drawing area and now what we need to do is we need to come back down here in the points section and instead of passing the local position only what we need to do is we need to pass in the ants instance of drawing area so let me just pass in the instance and you can see that it looks like this so the drawing area requires a point that is going to be the same point that is details start a local position and in the paint area that is the paint object we can pass in a new paint that is having the stroke wrap around the anti-aliasing to true like we have down here and the stroke cap of selected color and the width accordingly so we need to add the same thing the same set state function to this pan update here and we can just replace this set state with the new function here and only pan ends we need can we can keep the points - no because we want to detect if the user has picked up the pointer from the screen so that's going to be same so what we can do is we can remove the pain from here and we also need to do is we need to change this offset to drawing area and here it will calm us with an error so what we can do is we can just put in point X dots points and also here we can put in dot points because this is the offset now and also here we can put in a point so to resolve this paint issue what we can do is we can come in the if statement right here after checking that the point is actually not null we can just right paint paint is equal to we can get the drawing area and we can get the area paint from there and we can do the same thing in the else statement and it'll work so if I run the app right now and I go to the emulator and I draw on the screen and if I go to the color and change the color right here I can draw with a different color and if I change the stroke I can draw with a different stroke right now and if I make the stroke full you can see that the thickness of the brush changes and if I can bring that down and I can also paint with a different stroke right now and change the color again and paint with a different color so basically instead of using just simple offsets we're using this special class that is called a drawing area and it takes an offset and a paint associated with that offset so with that you're not only storing the offset but also a paint for each of the offset so this will help you in creating individual points on the P drawing area and then you can just update these settings and just draw with those updated settings instead of just redrawing the whole of the canvas okay so I hope you learned much in this tutorial and if you do please hit the like button and the subscribe button for more flutter videos coming your way and I thank you all for your amazing support on my channel see you next time peace you
Info
Channel: RetroPortal Studio
Views: 24,184
Rating: undefined out of 5
Keywords: flutter, flutter ui, flutter tutorial, flutter tutorial for beginners, dart, flutter android studio, flutter custom paint, custom paint flutter, flutter custom painter, custom painter in flutter, flutter drawing app, flutter drawing, flutter basics, flutter for beginners, flutter with dart, flutter widgets, flutter widgets for beginners, custom paint, paint application in flutter, flutter lecture, flutter basics tutorial, how to get started with flutter, flutter developers
Id: Zv5T2C1oKus
Channel Id: undefined
Length: 35min 19sec (2119 seconds)
Published: Fri Feb 28 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.