Android Jetpack Compose Tutorial- Mini-Course - Imperative vs Declarative UI Development

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so developing android apps has always been a hard task for developers if you have been developing android apps you understand that you have to understand a lot of things for instance to build a very simple android app you have to understand xml because you use xml to create that user interface and then you would use java or kotlin to create the logic that then connects to that xml and then which is the user interface and then magic happens well it's not all magic because you know there's more to that you know that you have to understand the android apis the sdks and a lot of things that you need to know or at least learn in order to build android applications and and that's how we've been doing things for since android started this is what we call an imperative way of creating mobile applications now we have a newer way of creating android applications which is a declarative way of creating android applications and you've heard a flatter you've heard if you're an ios developer you've heard of swift ui you've heard you've heard of react native you've heard of all of these other tools that were created that kind of shift the way development in general has been done you see that industry is moving towards a more declarative way what is this declarative way of building an application as the name imply is the clarity which means you don't have to specify the steps on how to build a button per se you now you just declare how you want the button to be shown and so it's a different way of thinking about creating mobile applications and that's the direction we're going all right so if you're new in this channel my name is paulo duchonne i'm a developer mobile developer android developer and a teacher so i teach people like you how to build apps how to program and how to think as a programmer so that you can become a well-rounded developer what is a well-rounded developer you may ask it's a person who not only understands how to build or how to code but also understands the other things that you need to know in order to become a solid developer in this video i just want to talk a little bit about the shift in the paradigm uh when it comes to building android applications in particular so we have jetpack compose this new toolkit that allows us to build user interfaces native android user interfaces that without having to put together the xml files to create a user interface and then have java or kotlin to then interact with this user interface to create the app and blah blah and all this moving parts because if you look at the way we've been building android applications you will notice that there's this tendency of having a lot of code boilerplate code which is in many ways it's just distracting and it's garbage and so you end up with this massive repo this massive code base that most of it it's just not doing much it's just garbage i'm sorry no that's a little bit harsh and so the declarative approach especially using jetpack compose it kind of gets rid of all of that now we just have kotlin you do have to know katlin of course but it's easy and you use kotlin to write code to write user interfaces to write android applications and it's really amazing and i've been working with it i've been working with it's it's great it's great it really is great so i'm very excited to start looking at the patterns in the industry where things are going in terms of how apps are being developed and how developers should probably start thinking about the great news is i'm going to show you how to build an android app using jetpack compose and the basics of jetpack compose so that you can see for yourself how awesome this is and so well enough talking let's go ahead and get started so to understand the modern way of building android applications we need to look at jetpack and what is jetpack so jetpack is a library of tools to help developers build modern android apps the most important thing is that when these modern apps are built they must follow the best practices so that's the whole idea behind jetpack so when you hit jetpack to talk about ways to build robust android apps that are flexible that are adaptive uh especially nowadays with a plethora of different android devices but following the best practices so the idea is to reduce boilerplate code and make sure that there is a consistency across android versions because as you know android is very fragmented there are different devices different versions different manufacturers and so forth and so to have some sort of a holy grail per se of how do we structure our android apps how do we build on our apps to have this consistency it's very very important and of course that leads us to follow best practices so jetpack library has a lot of types so here are just a few types we can find so the graphics navigation which allows developers to have a more consistent and a more consistent across-the-board way of of navigating users are using their app okay lifecycle user interface which is a big one we have media we have security data as well as performance and test so these are just a few types of library that come with jetpack so the android team with a lot of experience they had to come up with something that is more uniform as android is growing as the differences in devices also is growing and the whole industry in general development industry mobile industry is evolving so they had to come up with a solution at least close to a solution that could unify the the way android developers develop applications this course is going to focus on jetpack compose so what is jetpack compose jpeg compose is android's modern toolkit for building native ui ui is user interface so jetpack compose again goes back to that main reason that we have jetpack the the libraries right which is to write less code with powerful tools and also that will accelerate development so the idea is to minimize the work involved in building android applications really but not just building android applications but building application that with less code and applications that are consistent with the ecosystem android ecosystem and so forth that's what jetpack compose brings to us a modern toolkit for building native uis the great thing about jetpack compose is that it uses not only a separate set of kotlin apis application programming interfaces so essential libraries but also uses traditional kotlin's libraries this is really important because not only can you use the set libraries that are for compose or even kotlin of course but you can also use kotlin apis in general with compose it's really really powerful now why jetpack compose that's a very good question the industry is changing but let's let's talk about this now jetpack compose is a huge shift in android development because now we're using what they call declarative ui versus the imperative approach now what is this imperative approach well the imperative approach is what we do what we've been doing so far in android development okay and truth be told it is too complicated the way things are or the way things have been done too complicated because there are a lot of moving parts for instance the ui this interface is deeply coupled with the logic and vice versa which brings a very inflexible ecosystem coupled means that there is no separation between uis and the logic so there is this very togetherness that is not healthy per se which makes for very inflexible code for example one of the examples that we have to render for instance a list with a few items in traditional android development you will need to create a recycle or use a recycle view which is a very complicated class and this recycle view will need an adapter which because adapter will know exactly how to position the items inside of this recycle view and these items that we're putting inside of recycle view which need adapter these also will need a view holder which is a pattern that allows for the recycling of each item that is shown on the screen so this is actually a simplification that i'm putting it together but even though there are three steps that we need here it's very very complicated in fact if you have done traditional android development you will attest that this indeed gets messy that's the imperative approach this is just one example among many others but with a declarative approach in this case jetpack compose things are different in that they are simpler and more efficient so no more boilerplate code right because now what we're doing is we're declaring or describing in code what we want to see and not describing every step to get the result for example to render a list with a few items this is the same example we had previously in the imperative approach in jetpack compose all you need is a lazy column that's it because now we're just describing what we want to happen we're not going through the process of describing every step to get the result lazy column is the equivalent in this case of a recycle view we saw previously without all of the jargon that we have to know and we have to implement ourselves to get things done that is a new way of thinking about creating android applications using jetpack compose so if you're familiar with the imperative way of creating android applications this will be very very familiar to you so in traditional android development to create user interfaces we use xml right and then we connect the xml to get the actions right using an activity java class or catalan as well right and of course that's the only way we are actually able to create that application and then so that the user can start interacting with your application and the activity has the logic and the user interface comes from an xml file so with our new way of thinking of creating application jetpack compose that is no longer needed because now we have this declarative ui approach of creating user interfaces in this case also applications android applications we talked about declarative ui approach well this is what it means so this is how you would declare a user interface as you can see here this is what we call a composable function a composable function will compose as name applied some piece of a user interface so in this case here if you were to read this it would make sense first we were saying we want a card we are not describing how to create a card we're just saying we want a card and we're going to pass a few things inside of that card well this card is going to have a column which will contain a text not only text but it will also contain an image inside of this column right and of course there's some logic that we're doing there that we're making this column clickable and when this column is clicked we want to toggle between a certain state expanded or not expanded right so even if you've never seen this code before never even looked at compose this should make some sense right we have a card and we have a column inside of a column we are describing what we want we want an image and we also want a text this text is going to be animated some point right because i see there's this animated visibility that means it's going to be toggled between on and off depending on whether we have clicked the column or not that's it this is what we call declarative ui approach and this is how it's done with jetpack compose and that's what we're going to be focusing on in this course i hope you're excited to learn more about jetpack compose as excited as i am because i'm so excited to show you around and all right i'll see you next time let's go ahead and get started and create a brand new android compose project so open android studio you can go and say file at the top there are different ways to create a new project but this is how i'm going to do it and so and then we're going to have to get the empty compose activity so click on that i'm going to say next and here we're going to create the project i'm going to say give it a name let's say intro to compose so we're going to start from the beginning with compose so dissecting the major components of a compose project in a compose application so whatever you want you can name it and of course for a package name mine is pre-populated with this package name but you can choose whatever you want and make sure you have a location where you're gonna save this so i do have a sandbox android there and my my on my machine make sure we have android kotlin for minimum sdk i'm just going to go higher doesn't really matter at this point but let's go to 10 or 30 i'm going to go 30 at this point all right let's say finish so it may take a little while for the project to be created so be patient wait until the process is done and you can always see at the bottom here where it says gradle configuring projects so the gradle which is the machine quote unquote that does all the work in the background to validate to put together the entire project works in the background so give it a time and it will be done soon okay after a few moments you will see that our project has been created and all seems to be good let's go over what we are seeing here so to the left here you will see that we have our android project the great thing about android studio is that it gives us different ways to view our files so if you click at the top here you can even change the view of your file so you can go to project we'll just show the project view which means you'll have to drop in and look for files and so forth okay that's it that's a choice but i liked the android view because it just focused on the files pertaining to the application okay so you can also toggle it to close and open right the project tab here and inside we have a few things we have the manifest file we have the manifest folder there which has our android manifest and then we have the java folder here okay it's kind of ironic that it says java even though we're going to be using hotline but remember java and kotlin are interoperable and also the basis of everything really is java so kotlin actually is also on top of java so that's totally fine and if we open our android if we open java we'll see that we have a few packages here so a package essentially it's just a folder that contains related classes so all of these are different packages the main package we want is the first one here right and it's very interesting also to see that we have main activity which is exactly what's open and then we have this ui theme right ui theme so this is all created for us if you double click here you can see that this is color.kt so you can see color.kt holds all of the main colors that are used in our project and you can see if i go to my theme file double click let's just see code you'll see that somehow you can see that this is actually where the colors are being used you see here we have a vowel called dark color palette and we have dark colors and we're passing in this case the primary colors primary variant and so forth and we also have the light color palettes now this dark and light color are used for different modes they're for different ui modes we have dark mode and we have light mode so nowadays devices can be on dark mode or light mode so right off the bat our project gives that flexibility of dark and light mode and the colors that will be shown in one of those modes and then we have this type what is this type we'll type here we have a few things this is where we can set our typography so talking about styles fonts and sizes and so forth there's a lot of things here but but we have the basics set up if i say you see here says typography the body is set to this style okay which means if we want to use for instance we are in our main activity we want to create a text and we want to pass the stage style we can use this typography here right variable and invoke the body to get the body style for the text we want to show these are preset values and obviously we can change those as you see here other default text styles to override we can override all sort of things so this is something that we're going to take a look later obviously all right so and we have shape so for shapes here we can actually use certain predetermined shapes for our user interfaces for our widgets as we create them in our main activity or anywhere else in our application so we can create our own obviously but there are a few that are set as a default for us to use as you see here i have valve shapes and we are getting the shapes as you can see here if we get a small we're going to get a rounded corner shape of 4 db which means if we use for instance a card and we want to have those rounded corners we can right away say one small this is the value we're going to get for our rounded corner shape for a medium this is what we get and large that's what we get right so all of this is given to us and we can always override and customize and of course we have our resources folder here and then we have our drawable here and our resource files okay resource file and then inside we have this travel folder this is where we can add images and so forth and we also have the values folder here where we have colors.xml these are also the same representation of the colors that we saw earlier that's used still in android development okay these are still used of course internally because remember even though we're talking about compose we're not saying that everything is stripped away in terms of how we used to build android application this is just a quick overview of what we have here and i do realize if you're an android developer already this may be very mundane to you and you can always fast forward or skip this but it's fine but i just thought it would be good for everybody to actually get at least some idea of what's going on here all right so we will be spending a lot of our time in this folder here so in our main activity because we are creating a compose project here this is what we see let me go ahead and close this down now we can split between code just code and split to c here the preview if you refresh we should see a preview in a second okay after a few seconds you can see now it says here hello android now it's important to know exactly where is this being previewed from let's look at our code you may think this has been previewed from here because this is where it's been called but that's not true if we go down here we can see that we have this default preview in fact we should have a hint here that says default preview so this is indeed the name of this function here okay now it's very interesting to also keep in mind that every composable every composable function has to have this at composable annotation so annotation is a way of adding meaning to certain functions or classes and so forth to add metadata to say so that the compiler can know exactly what to do there will be more directions as to what is it that it's going to be added onto the function or class that is being annotated that's the idea although in compose the add compose is not necessarily annotation as you would have in any other circumstances such as in java and even cuddling in in a sense so look at this as more of a keyword that tells the compiler that okay this is indeed a composable function which means which means it should construct a piece of a user interface but again what is really making this available here in our preview is this at preview annotation there and you see also if you hover over anywhere we get some documentation this is really really really really really really important and cool so if whenever in doubt you don't understand is for example what this is or what something is you can always hover over and you have a preview you can see here it says this is a public constructor preview very good that means we can pass all these all of these parameters and you can see one of the parameters we pass is show background boolean to true what happens if i say false ah let's test things out aha there we go if i say false then we lose that white background all right back to true and if you preview again or actually hover over i should say the preview you can play around with anything else that you want here like a name you can change the preview name to something else i can say for instance name is equal to me like this and voila the moment you do that you can see it's changed to me instead of default preview so if you don't put anything specified it's just going to go and get the name of the function let's rebuild again didn't have to do it you can say says default preview okay so and next you can see here we have the intro to compose theme this intro to compose theme you notice it will take the name of the application that you created that you typed in when we're creating this project right so what is this well it's a pending theme so you could imagine that this is theme related if you hover over again you can see that this is at composable which means is indeed a composable itself so it's public fun and intro to compose theme and then here you can see that we can pass a few parameters okay and these parameters are optional at least the first one so the first parameter is dark theme so it respects it expects a boolean so as the name implied dark theme will allow us to say okay we want this to show in dark theme mode or not and then we have this content here the content is a composable function that is expected here interesting and the beauty here because you remember if you have been following us or if you remember your cuddling you remember if you have a function that has a function another function as its last parameter which is this case then that means that we can use a lambda as you see here we can use a trailing lambda to invoke this content last parameter function and of course it's expecting at composable which means expects any composable function to be shown or to be to be added so in this case here that's why you can see we have greeting which indeed is a composable function if i remove this composable there we can have a lot of issues because you're going to say well function which invokes a composable function must be marked with ad composable annotation so this is lesson number one to say that you can only call other composables inside of composable functions very good so we're making progress here we're going really slow because because i really wanted you to get to know what we're dealing with in a very simple project this is just a default project a default jetpack compose function so we're going to go through a few things here and keep digesting so we can wrap our head around compose earlier we were able to run this app onto our device you can see here emulator and it says hello android is really small i apologize but believe me it's there and i know you're following along you should see hello android and we said that we're able to change the color of the surface the surface is going to enclose whatever is inside of our lambda trailing lambda there in this case we are calling greeting which is you see here it's another composable created passing name and just text that says hello and pass that name so hello android is there if you hover over our surface again you'll see that there's this parameter we can pass or in this case argument that we can pass called modifier a modifier is a very important one so let's see how this works so i'm going to say enter and then i'm going to say modifier my slash modifier is equal put comma there modifier we're going to invoke modifier and the moment we do that modifier we can go and start invoking the methods that come with modifier so in this case here let's say i want to go and find fill max width so the fill max width what it's going to do is it's going to fill the max width that is available let's see how this works so i'm going to go ahead and run this ah i actually got the phil max height not width but you can see here is the same idea so because i said fill max height you notice that we have the entire height of the entire screen if this screen was larger than this it would have done the same thing it would have taken up the entire screen obviously we can do the same thing with the width which is in first place that was the first thing i wanted to do but it's okay this works so how do we get to fill max width well because modifier we can chain all of these calls you can say enter say dot again because we're still in our modifier right i'm going to say fill max height in this case width all right and there we go if i run again voila now you can see that our entire surface from not having anything it was just constrained to whatever we had in this case a text now it's showing now it's taking up the entire space and what i can do also i can continue chaining i can say dot padding for padding i can pass all different kind of paddings right there are different functions with different parameters but i want all to say all in this case named arguments there i want to give let's be exaggerating here maybe 59 dot dp i have to pass that dp because that is the unit that is recognized in android okay so 59.9 dp that is how much padding i'm going to have around this surface is that true let's go ahead and run again and see there we go so we give 59 dp around the entire surface when it's around it isn't it around so now you can see that the surface has shrunk a little bit right all sides by 59 dp units so you can see by using modifier you can modify you can customize the views the ui instantly and quickly this is very powerful and we're going to be using it a lot obviously i went straight to our set content and in that case the to preview or to see the the changes i have to run right i could have done the same thing obviously here as well in our preview or inside of this composable or inside of this composable it doesn't matter right but i just know that at the end of the day if i want to push all of those changes so i can see in a screen i have to put inside of our set content it makes sense this is where we're setting the contents of our app very well so this is not a big project as you can see it's just a way for me to show you small things here and there so that you can still get the full idea of what compose is and how powerful this is now the main thing you have to understand here i would like you to really take away is that a composable function such as this we didn't create this one although it's very similar to this show age but a composable function is very powerful in so many ways number one a composable function is annotated with the comp at composable annotation so all composable functions must have add composable that is not negotiable so this annotation what it does it informs the compose compiler that this function is intended to convert data into ui because that's all we're doing here a compose function converts data into ui what that means is what this means is that this greeting or this show age doesn't matter but this greeting here what do we do we're passing data right that's all we're doing and this data is actually being transformed or converted into a user interface voila you see there hello android that is the power of a composer function that is the power of jetpack compose ladies and gentlemen because a function takes in data the composable functions then accepts those parameters right we can pass as many parameters as we want and accepts it and then we can do something in this case we're calling yet another composable that we didn't create hover over it's composable it's got a lot of parameters passed and arguments that we can pass to also set it up and transform this into an actual user interface widget so this is the thought process how you should start thinking about compose if you're coming from for instance android development the imperative way of android development where you have xml and then you have the java class or kotlin class and then in activity you use the mechanism to get those xml uis and then do something with it to give it logic right this is different in our case here now in compose we are converting data into ui the other thing you will notice about composable functions to keep in mind is that since they emit ui they don't have to return anything because they describe keywords here ladies and gentlemen they describe the desired screen state instead of constructing ui widgets here we're not going through the process of constructing this text widget what we're doing we are describing what we want to happen we want what we want to happen is a text to show hello and name that's been passed here you notice also the naming convention all of the composables start with uppercase letter any other case if it's not composable you will start in kotlin especially in many other languages you start a function name or a method name as they may be called with lowercase that tells you something the difference here this is not a normal per se function it is a composable function it composes ui it describes the desired screen state instead of constructing ui widgets so everything you see to the right here comes from our preview so any function that has at preview will be previewed here that means if i come here and create another composable we need to start at composable and there we go the id was going to help us hit enter and then i say fun show age for instance in this case i'm going to pass age it's going to be an integer type and then here i can say text hit enter that's the first option and all we want is the first one which is just a simple text so hit enter and then here i'm going to say age like this okay now we still may have the same problem if you hover over we're going to say okay some issues are there now the reason why i know what's going up here if you hover over is going to say parameter h is an integer but this text widget here only allows us to pass in a a string so i'm going to say 2 string for now just to simplify our lies okay so we have this show age we pass agent so essentially similar to this okay so what happens here if i want it to be previewed here right i can do so how do i do that well at the top i'm going to say at preview something like this now we have a problem because it says if you have over it's going to say composable functions with non-default parameters are not supported in preview unless they are annotated with preview parameter what this means is that well because we're saying age here we say it's integer we need to pass some sort of default value so that it's picked up in our preview here so when you do that you say equals 12 and you can see this is gone and now we can see it says show there but we don't see anything let's go ahead and refresh and voila you can see you see 12. if you click it's going to go straight to where we created that text there also you can see that we have the show age which is the name of the composable function that we've created now because this is a composable i could call show age inside of our intercompose theme as well so at the bottom here i can say show age and of course because we have a default value for age nothing really happens but i can say if i want to age 34 as such you should see something here let's go ahead and refresh and voila now here's the problem it's there i can promise you that it's there but it's on top of each other what's really going on here well what happens is because we're just passing inside of this intro to compose theme there's no layout there's no way that compose will know exactly where am i going to put this so what happens is that it just puts things on top of each other so if you really want to see what's going on we can put inside of a column so column will always put things on top will always put things vertically right below each other so i'm going to say column start typing column as such and you can see this is indeed of course another lambda everything is a lambda and we can pass all modifiers and so forth here to structure our column but for now it's okay we're just going to go and put all of these inside there let's go ahead and refresh and just like that now you can see that we have hello android and 34 because you put that inside of a column which is going to structure everything vertically again if you want to know more about a column you can hover over and you can read all of this stuff okay so now what is up here let's look at the set content so the set content here has the name implied this is where we're setting the content so that it can be viewed on an actual device or emulator so forth right so in this case here we can see we have a main activity inherits from component activity we have on create so this is the entry point to our entry point to our project so here we're setting the content yet another lambda and we're passing the intro compose remember this guy from down here right same guy same thing right sets up the entire view according to the default theme okay of the project and then another compose we pass inside here the surface which is another which is another compose okay which is not a compose and it has also trending lambda so everything is about lambdas here very good so here it says a surface container using the background color from the theme so a surface it's just in the main the most primitive the most basic canvas and as you can see we can pass a few arguments here color and we set the color from our material theme that we saw before we go to colors and get the background okay and that's where we're passing greeting android so this is going to be called when we run this app on the emulator so if i go ahead and run this app make sure you have of course an emulator so the idea is that when we run we should see this creating android okay you can see after a few moments you can see hello android so whatever we pass here instead of that content it's not going to be in our preview right so the preview is to preview whatever we're doing we're calling great a greeting the same thing that we see here it's for us to preview we're also calling another composable that we created at the top there which incidentally also has preview we can remove that preview if we wanted to and so forth so whatever we pass here inside of our set content it is indeed what we see there the beauty also here let's toggle the code only is that if i set a different color let's say i want say colors and let's see what else i'm going to get let's get primary to see what's going to happen let's go ahead and we run this and you can see now the background of our surface which is this right that's enclosing our greeting which is what we have at the bottom here it's a composable it changed the colors now all right so here's what we're going to do next we're going to create a very simple application where we're going to have a button of some sort or tappable ui widget and when that is tapped right this circle is tapped we want to increment the amount of money we'll see at the top there so it's a very simple app but it will give us some insights into compose and how certain things work all right let's go ahead and get started so back in our project let's clean things up so there are a lot of things that we no longer need in this case i'm just going to get rid of all of this okay and then get rid of this so just for testing purposes i'm going to get rid of this composable as well which means this needs to go we can't do that anymore okay all right so the first thing i'm going to do here inside of our set content we are passing of course the compose theme and then we have a surface we talked about is taking over the entire screen at this point because we have max height and max width we add some padding and at this point let's just get rid of that because we're not going to need that of course forget our comma there okay now one thing i want to do is in fact let's come back now one thing i want to do is i want to remove this surface outside into its own place so i'm going to create another composable here so say at space add composable as such say fun call this my app okay and then for this my app here what i'm going to do i'm going to get this entire surface there because this is going to be our canvas per se i'm going to put it here as such okay and then for now inside here let's just say text and say hello okay i'm going to call my app of course inside here my app as a composable very good and then also my app here so this is just a very simple way of organizing our composables so we want to have it inside here because we want to be able to see in our preview here so i'm going to go ahead and refresh and there you have it so we get what we are looking for and everything you see to the right bottom right here we can actually toggle the percent we can actually toggle the views here i can maximize so zoom in or minimize zoom out so in this case if i go to click the zoom to fit screen click here you can see it's going to go ahead and zoom to fit this real estate we have okay all right so we have everything looking good so there's the color primary color because that's what we chose the other thing i can do if i want to for instance add a customized color i can get rid of this and i can invoke color class as that and pass and pass in its constructor i'm going to pass the code that will represent a different call that i want all right so to pass the hex code as a to pass a hex code here which will represent a color the first thing we have to do this is zero x and then i already have the color so i'm just going to and then i already have the color somewhere i'm going to find it and i'm going to add it there the other thing i'm going to add i'm going to say ff to begin with like this and then the actual color okay oops like this all right there we go so this color here doesn't matter really you can put whatever you want but i just found that color to be great so i'm going to go ahead and refresh this real quick to see the differences okay so there we go we have that very nice color there very good so that was a test i'm going to get rid of this and continue now the next thing i will so what is all i want to do first of all when i create a circle inside here the different ways to create a circle so i'm going to create yet another composable here say add composable as such and call say fun and say create circle like this okay and inside here i'm going to create a circle how do i create a circle well as i said there are different ways but the basics is that we need to have some sort of the baseline or we have to have some sort of a main composable we can call and then we can modify it so let's start with a card so i'm going to say a card like this so it is a composable hit enter and for now also i'm going to go ahead and make this previewable so that way i can also preview it right here so add as such and in this card here if you hover over you'll see that there are a lot of arguments that we can pass most important one we have this modifier and we have the shape background and so forth and one thing that is very important the order in which these are added is very important as well okay so let's start with modifier because it will allow us to modify as the name imply our card okay so inside here i'm going to pass say modifier as such and the id will help us just hit enter and then pass modifier and then we can call whatever we want we can use padding just put 3 dot dp right and i can chain our modifier as i've shown you before so what i want to do is for instance i can say dot background and give a color to the background all sorts of things but the other thing i want to do i will stop with the modifier for now if i hover over here there are other things we can pass the other one is shape what shape do i want this to have or to take so i can come here put colon or comma i should say and i'm going to say shape now there are different kinds of shape we can pass in this case i'm going to just say circle shape as such so this card as it is right now let's go ahead and run this or refresh let's see what's going to happen you can see it's very small there is the card right it doesn't have much because number one we don't have a size and it doesn't even show the circle shape let's see something here if i come back to our modifier say dot i'm going to say width as such and you say width and also there is height so we can specify the width and height but there's also another way of doing this i could also pass this size so there are overloaded sizes function size functions here we have this size here you can see we passed just one size right if you pass that one side that means it's going to take up for width and height but you can specify size for width and height you can specify size in and so many now let's go just to size and say i want this to be about 45 dot dp okay like such let's refresh and just like that ladies and gentlemen you can see how we have our circle very good so again because of modifier we say padding is going to be about 3 dp and the size is going to be 45 so the smaller the size obviously the smaller this circle is going to be and we say the shape of this card is going to be circle shape this is given to us i can also say rectangle shape like this if you go ahead and refresh you should see rectangle and voila you can see there it is now the reason why it's square is a rectangle per se is because of the size that we gave we we gave 45 for all of height and width that's why we have a square okay very well so let's go back to circle what we had before so inside of our trailing lambda here that means we can add contents that we want to see inside of our card so in this case i can say text like this and say tap like that let's refresh and you can see we have tap showing there but we have a problem here the tab is not in the middle we want it to be in the middle of our card now there are different ways to deal with this issue one of the quicker ways we have here to force the tab the text we have here to be in the middle is to wrap this text into a box because a box will have because a box will have an arg because a box will have a parameter that will allow us to set whatever is inside of this box to be in the middle so what i'm going to do a tab i'm going to say box and there we go the first box there and i'm going to get all of that input inside and if you hover over inside of a box it is indeed a composable everything is pretty much composable in jetpack compose and you can see we have modifier as the first parameter there and we have the content alignment ah this is really good because it will allow us to align the contents inside of this box which in this case is the text so i'm going to say content start typing content alignment it expects an alignment object say alignment and there are different objects here or different variables that we can pass so the alignment we want is the center okay not top center we want just the center as such if hit enter and voila okay there we go so let's see if it's true if i refresh this i should be able to see tap now in the middle so tab is now in the middle of our circle that means if i make this a little bit bigger you can see it doesn't matter how big or how small it is our card in this character circle uh it's always going to be in the middle okay there we go and voila nice so we're able to put tab in the middle of our card which in this case is a circle now we want to make sure that this tab here or actually this whole card when it's tapped or clicked something happens so we want to make this whole composable this whole widget here clickable how do we do that because remember this is just a card if you have over you see there's no on click event that we can pass directly ah but here's the thing because of modifier we can actually invoke a clickable event look at this if i say dot clickable i can make anything clickable if i hit enter you can see now we have another fill in lambda here is where we actually add the event here is where we capture the clickable event in fact if i just come here and i want to log out just for testing purposes i can say log d you can see we have an option now of creating a log hit enter then there's this code completion so for log d for log debug we need to pass here a tag let's say tap like this circle is there i'm going to circle tab like that so now if we run this we should be able to when this whole entity this whole widget is tapped we should get this message we can also deploy this specific preview here onto the device by clicking this button there so right click there actually let's look at our emulator and we should see hopefully soon something let's go ahead and just go to code so we can save some space okay there we go it's very small i can make it this little bit bigger so you can actually see very very small but there it is now let's see if this works i'm gonna open logcat and i put tab here for our regex so if you tap you can see says tab there so each time i tap it's going to show okay you can see all of the tabs are being shown there all right so it's working all we have to do is just to through our modifier to say we want this car to be clickable and when that happens we want in this case a message that says create circle tab which is exactly what you see okay so as you can see when we run it it's really small we want to make a little bit bigger let's maybe make this 105. there we go it's really large the other thing we can do because it's a card if you hover over again you see we have this elevation so this elevation what it will do it will elevate the button so that we have a contrast between the button and the background because as you see here right now it's very minimal the contrast so hover over to make sure we know exactly where that so anytime after our shape we can add elevation so so i have modifier there and we have shape i'm gonna just put here at the bottom i'm gonna say elevation and give it about four dot dp like this all right let's go ahead we can stop this if we want it and go back to split mode and make this that size and let's go ahead and refresh we should see some differences there all right there it is it's car to see let's go ahead and just run all together on an emulator hopefully we can see aha now you may ask okay what's going on here why is that we don't see anything on emulator remember earlier we actually created or clicked deploy preview which just deployed this not necessarily the app so that is the distinction another thing here you remember that we're still constructing our circle here and we have in a preview mode for this create circle we're not calling it anywhere so if i call it inside of my app because remember my app is being called inside of set content that should work so here i'm going to say create circle like that now if i run i should be able to see that circle ah there we go there's our circle the circle is not what we're expecting but it's okay we'll fix that so what's happening here is that because in our my app here we have a surface and we are saying fill max height and fill max width so the circle now is taking up the entire space where there's nothing else inside of this surface we'll fix that but nonetheless you can see now that there is a distinction between the background and the button because we added that elevation here so the bigger the elevation the more contrast you will have okay you can see at the bottom here actually it's probably better there's some sort of shadow happening there okay now if you click you can see now this will work if you go back to logcat you can see that tab has been working each time you tap everything still works right so next we need to tackle this problem we're having here which is is taking up the whole space which is exactly what we told the surface to do but that's not what we want we want the button to hopefully be in the middle of the screen so i want you to think about this what would be a way for us to make it so that this button is in the middle of the screen so let's solve the issue we have here our our card or circle per se is taking up the entire space in our surface which is not what we want so what we can do actually and this is going to help us because in the long run that's what we want to do in our ypk because we want to make sure that we have another composable in this case another widget on top here right what we want to do is to wrap our circle inside of another composable okay so what would that be well that composable is going to be a column we want to be able to have widgets that are from top to bottom that are lined up vertically what i can do really here is i'm going to put inside of a column because that's what i need hit enter and then we're going to get our friend here if you just say command shift and arrow up control plus shift plus arrow up on windows it's gonna take this entire line of code inside of column just like that if i go ahead and rerun this real quick we'll see that a few changes will happen one important change that is and there we go now you can see instead of taking the entire space you wouldn't put a column it reduces the size to the correct size which is exactly what we want now we still have a problem here we want this button to be in the middle of the screen in this case going to be in the middle of our surface because this indeed is the outer canvas where everything has been laid out so if you hover over again our column here you will see it's a composable and we have that modifier but most importantly we can now align things vertically or arrange things vertically as well as arrange things horizontally this is really helpful because that means we have a lot of control of whatever we put inside of our column so let's go ahead and say i want this to vertically so say fur is that wait a second vertical arrangement so i can arrange vertically by passing arrangement like this i want this to be center so there are a few options there's top there's center there's bottom and so forth so we're going to say center like this and let's go ahead and run real quick and see what's going to happen aha it is center yes however however you see we said vertically we want this to be center so vertically it is indeed in the middle if we go top to bottom but we also want to horizontally be in the middle how do we do this well we're going to go ahead and say horizontally let's put add a comma there let's say horizontally i said align i want center horizontally like this if we run this again and voila now the button is indeed in the middle of the screen which is exactly where we want now remember i'm passing inside of my app here which is being called in our set content and my app has a composable we have a surface and inside of the surface this is the surface with this color inside of its surface we added a column and we made sure that everything or anything that is inside of this column is going to be vertically arranged center and the center horizontally arranged horizontally that's what we get there very good and of course inside of our column that's where we create the circle we call create circle which is indeed this composable here and right away you can see that indeed we have everything in the middle as well right because we're just previewing we've now passed the my app which contains the surface and we're passing there's a column there and then we have call and then we call in the create circle and there you have it so next what is we want to do well next we want to pass at the top here what i can do actually i can go straight and put a text right and this text here will say what well i want this to say hello in this text here i can say text now there's another thing to notice very interesting here is that we can actually pass named arguments here and it's really a good idea to pass name arguments because especially when we start passing a lot of arguments into our composables here things get a little bit chaotic if we don't add these named arguments okay you don't have to in fact you can just go ahead and just say something like this hello and that still works but it's a good idea to always pass the actual argument to name something like this and then pass the values to data in this case so for now i'm just going to go ahead and say 100 like this of course this is going to be of course this is going to be inside of double quotes oops let's go ahead and refresh and there we go so it's hard to see but there it is and we have our tap button which is a button now because we made it clickable and then we have the text there now imagine that we want to put some sort of space between this circle and this text how do we do this well there is a specific composable that we can use called spacer like i said spacer like this again you can pass a modifier the modifier in this case could be a few things so i'm going to say modifier let's go ahead and just type it all out modifier and because i want the height of this modifier and because i want to make sure let's go back this let's go back again here i want to make sure that the height right between this widget and the next one there's some sort of separation so the more height i have the more separation i get that's why i can then go say modifier that height and give a value let's say of [Music] 30 dp let's refresh and there we go you can see there is that space that we need so the more space we give that's for 100 you can see the greater this number is in our height the more space we'll get so we have the things set up as we want they're looking really good let's go ahead and run one more time onto our emulator so we can see exactly how all of this transpired there we go we have our app is working looking real good but you notice that the text is really small here we want to make this a little bit bigger how do we do that well funny you ask we can go inside of our text here if you hover over again inside of our text remember this is still a composable function we can pass of course the text we pass the string there it is but we can also pass other arguments that's the beauty again of compose here of course we know we have the modifier our good friend we can pass the color font size font style and so forth but you see that the last one we have here is style this is more free form way of styling our text i'm going to use that so i can show you so i'm going to say comma i'm going to put style and we can pass a text style type i can start saying text style like this and you can see we have text style default and many other we have there's text style and you can see if i hit enter inside of a textile we can pass all kinds of arguments oh this is beautiful so we can really customize our text to our liking look at all of this right so in this case here i can go and change the color i can probably say would enter a new line i'm going to say color and set color i'm going to use this color here and then i want this to be white okay and then i can say option space and then i can say font size right for font size i'm going to say 19 and now i'm going to use a different unit which is sp okay so whenever you want to use font sizes sp is the recommended so i'm going to say alt or option enter to import sp library there we go and now if i run this there we go it's a hundred still small so we can play let's say 39 that's much better okay because we just change a style an attribute here you notice that we didn't have to run everything and to see the changes so this looks great maybe 30 maybe 35 can play with this forever okay so there we go it looks really good and we can make it bold i can say font weight and then i have i'm going to say font weight and then go get bold the other thing i can do i can start typing bold like this and the id will actually give the option for bold or extra ball let's say extra bold because we're feeling extra today okay let's go ahead and run this okay there it is so we were able to put together this user interface okay so it's very simple but at least but at least it's going to guide us understand how things will work how to compose no pan intended how to compose a nice user interface as you see here now obviously the whole idea is that we want to make sure that when we tap as we tap this button we made this a button it's just a circle we want to increase this number here right we'll start at 0 and go from there and that's what we're going to be doing in the next video so what we want to do next is to be able to go to our circle or create a circle you can say command enter to go to the definition or control b on windows as you can see at the bottom here and so what we want to do is when the circle is clicked we don't want to just to show what we see here we want to be able to do something ideally we want to be able to increment this value here so let's test things out first we want to be able to increment a value which means we need to create that value or that variable so let's go inside still inside of our function here outside of our card and i'm going to initialize a val let's say money counter and set that to zero that's the first initial value okay and so here what i can do i can hopefully say something like this money counter is equal to money counter plus one so each time that we click on this money counter we are going to increase it but of course i'm going to have issue because of course i said val but this should be var so that we're able to mutate this so this is immutable so if you have val that's going to be immutable meaning we can't change it but the var will change it makes sense because we need something that changes and we still have an issue here or rather a warning so let's hover over and see what's going to happen it says he'll replace with operator assignment so yes let's do that it's smarter this way either way it would have worked but this is succinct and the way we should always do it okay let's run this uh actually before we do that let's go ahead and say log d again because we want to see in our console this value so i'm going to go ahead and say my counter to see if it actually changes anything money counter that it is okay and i'm just going to say counter all right let's see let's go ahead and run let's go ahead and also open our console there and i'm gonna say i'm gonna look for counter right to so we can set results just for counter okay let's go ahead and see all right so i keep clicking and i don't see anything maybe i missed something let's see is that true okay let's see counter okay that's nice circle one and it works fine okay because we can see as we have the values being incremented that's fine now let's let's see something else here because the idea really it's not to log these values it is to hopefully see the changes somewhere in our ui let's change for instance this tab and say instead of saying tab i'm going to attach another variable here in this case money counter variable let's see what's going to happen now so i'm going to go ahead and leave that as it is i'm going to run this so the idea is that as i tap i should see money counter also going up just like we saw here right let's wait for a second okay let's try again click we notice that the counter works fine two three and so forth however when it comes to changing our text here you should say tap also incrementing right first and so forth this tab money is the same variable that we are showing in our log here yet in our log it's going up but at the moment we attach to a composable a ui piece of ui here ui widget then we don't see that change what is happening here well this is an important concept that we really need to understand in compose which is in order for us to see changes in our text here or in this phase in this case in any other composable function as you see here this is not going to do it the reason being is because whenever we want to change something inside of a composable function in this case a text right we need to redraw that composable which means this text here has to be redrawn with the new value and if you remember correctly what we talked about between the difference between the imperative approach in android development versus the declarative approach in a declarative approach we are passing data through the composable functions and then the composable function reacts to that data that's the idea so how do we make this to react to that data which in this case mean to rerun itself to redraw itself by the way this redrawing itself it's called recomposition in compose and we'll talk about that in a second for that to happen there's a special variables that we need to pass here or we need to create for this to happen this special variable will create what's called an internal state because we need that state so that we can control that something has changed that way this composable text here will know oh my data money has changed that means i have to redraw myself recompose myself to show that new change interesting that means then for in our case here what i will need to do i'm going to say var money counter i'm going to use delegation here i'm going to say bye to delegate this responsibility to some other class we don't even have to know about i'm going to say mutable state of like that and this mutable state of i'm gonna pass a value of zero in the beginning so what are we doing now we are saying this my counter is going it's not going to be just an integer it's going to be something that is wrapped into a state which is needed for us to be able to obviously here to recompose our text so it gets the correct value as we change as the value is changed obviously so we're going to have some issues here because we need to import a few things so just hover over like this you can go ahead and import or you can just say alt or option enter it's going to start importing everything that we need we imported that but we need to keep importing until that it's not read anymore now we have another problem here if you hover over it's going to say okay creating a state object during recomposition without using remember so that's another concept here that needs to be addressed the idea is that when state changes obviously the ui must also change that means then we need a way in which this function here composable will always remember the state so that's what's happening here so we need to actually say something like this so i'm gonna say here by and then put start writing here remember like this hit enter and remember is a lambda so now we're gonna take this mutable state of just put that inside there so what we're saying now is that yes we are going to create a modable state of and we pass the value here the initial the init value is zero which will be implied to say this is indeed an integer and then we're going to have to remember that state and all that is going to be and we are going to put all that value inside of my counter so now this no longer is just an integer if you have over it says my counter is an int however we wrapped it inside of a member as well as a mutable state which is really important so now if you use my counter things are going to work so now let's see if this works i'm going to go ahead and run this okay let's see if this is going to work remember i still have counter here on our debug and it's open if i click and you can see make this a little bit bigger you can see that tab is one two and is working as intended so what's happening here because we have that state attached to my counter and it's being remembered what's happening now the text will know that okay this is being changed the moment that we click as since it's been changed the value is changing and i will remember that because it's a remember because we have a state and it's going to be remembered what happens now this is being recomposed meaning it's being redrawn again each time that this value is changing that's why we're able to see what's happening here 10 and so forth and just now you've learned the most important one of the most important concepts in compose which means we need to have a state for us to be able to see changes to update a user interface in this case this text or any other composable function out there so you see the difference here is that we have data and we pass that data through our widget in this case our compose function and then that's when the compose function will then come to live or will update itself because it will know now it's time for me to update myself because i have new data and that's why this is working now very good so now we're going to take a little break and go and understand a few other concepts that surround this one concept we've learned right we need to understand a little bit more how this recomposed because i've talked about recomposition and so forth what is it and how all of that works and then we're going to compare again the imperative approach versus the declarative approach which is what we're using here now let's look again at the imperative versus declarative approach but let's dig deeper so that we really understand what's going on or or why compose is really great at what it does so in the imperative approach of android development so you would have android layout so you have a lot of views that you put together to create a user interface which means that you have two sections going first is going to be the layout file which is usually an xml and then you would have an activity right so in order for you to be able to traverse or to be able to go and get for instance a view or or in this case a widget could be a button a text or an image or so forth in your coding activity you would have to use functions such as find view by id right so what are you doing when you say find view by id is that you're traversing this tree that is created containing all of these widgets in the background which as you imagine takes time and is expensive in a sense that it takes a lot of memory a lot of computing power so one of the things that also you have to remember is that in order for you to change let's say a text view you would have to use scatters etc so that means you have to say text view set text to a string or a button dot on click and so forth right so you actually have to manually change the state of the views first of all you have to traverse the widget tree which is very expensive it takes a lot of computing power and also it increase errors because it may happen that the view you're trying to find has been long removed by another function by another class so now you are looking for something that doesn't exist or if you are trying to update something that doesn't exist then you end up with a lot of errors and your app may crash and also as i said you are directly changing the state of the widget manually when you say text view that set text you are directly going and changing that state of that text field which is not a great thing because it pollutes your whole state management and your free app and you wound up with a lot of issues and you potentially may wind up with a lot of problems so this is the imperative approach and the fourth pitfall is that you may end up with also update conflicts so update conflicts may happen for the same reason i said you may try to update something that was already updated and now this state is all messed up because there are there isn't really one source of truth when it comes to state all of these are some of the pitfalls we get from the imperative approach of android development now when we go to the declarative approach in this case jet jetpack compose things change dramatically the same idea we have right so we create views in this case we create declarative uis right which means now the uis are built and updated differently than before what happened now is that when something changes inside of our widget of tree in this case all of these composable functions or widgets inside of your app what happens is the system goes out and updates the screen but most importantly goes and only updates what needs to update the widget or the function that needs to be updated only this is what we call recomposition the beauty here is that we no longer have to manually update each widget so you remember the text view that's set we no longer have to do that because we're declaring what we want to see and we're letting the data dictate whether that view needs to update or not and also most importantly we no longer rely on xml to create user interfaces now everything is done in one way using one language in this case cuddling another main concept in the declarative approach is that data is passed down what that means well in other words we pass data into our main composable and then the other inner composable functions in this case in return will react to it which means they will update and describe the user interface as they say fit so now we have smaller composables functions there are waiting or receiving data and be reactive as they get that data that's really really powerful and on the other hand on the other side too what happens is that events go up what that means is that an event is triggered for instance if a user interacts with for instance parts of a story widget as you see in this diagram here what happens is that the app logic will know that there's that there is an event that is happening here and it will know whether it is a new data that's been posted that been that's been sent out that way other parts of the our user interface right other composables will also be notified that oh something has changed we need to do something if necessary again that recomposition is happening here remember if necessary that is the most beautiful thing about compose is that it does not go around and compose or and recompose i should say all of the functions no it just goes and picks the one that needs updating now we got rid of all of the clunk we got rid of all the coupled situation that we had between layout xml and activity because no longer have to go and set my data or the state manually using getters and status and so forth now we're letting the data itself mandate everything the data and the events so this is the declarative ui model just because we need to have some sort of definition recomposition is the process of calling your composable function again when inputs update is the process of calling your composable function again when inputs change and this goes back or takes back to what we've been working on which is that circle that we tapped what happens the recomposition happens because every time we change this state of our counter the compose compiler will know that okay just that text will have to recompose because the data has changed not anything else just that text all right so let's go back to our code now that we have we understand at least the advantages that we have when using compose versus the old way quote unquote of doing development now there are a lot of things that i went through here but i hope i broke them down in such a way that are easy to understand and you are welcome to re-watch this video that way you have certain concepts that are really really important for you to really understand composed jetpack compose so if things are not really making a lot of sense don't worry just watch the video and remember we're still in the beginning stages of this course so there's a lot to learn and these concepts or these concepts i should say they will come up over and over and by the end of this course i promise you you will you will be good you will understand all these concepts because you will have done a lot of work yourself to really understand how all of this work but i want you to get this concept you change the way you think about development okay so let's go back to our code so back in our code here we see that this is working perfectly fine we can see that tap nine or tap button is incrementing because we are composing and all the great things are happening now remember that you have no pun intended you have to pass to remember here because remember keyword can store immutable or immutable object so if values change right in this state here it will trigger recomposition which is the refresh of the ui but not just the whole ui but more specifically in this case it's going to be targeted to this text here okay this is what this is what is changing right we're changing the user interface in this case by passing in our money counter data okay so we've got a passive we have to have a remember and then inside a multiple state of to create the actual state and remember we'll remember that state okay now this is one way of actually creating a remember here right the other way is as follow i can say var money c just to differentiate and i'm just going to go ahead and say is equal to remember like this and then just pick the second one and then we can pass our mutable state of and pass in this case zero now if i change the whole thing let's just use that one let's comment out this money counter there you'll see that we have a problem the reason why is because the way we have created this variable here money counter now we're not delegating we're not using delegate buy here it works but we have to change a few things because now this money counter is not going to work because it's going to say if you hover over its money counter it's just immutable state it's not just an integer but it's a mutable state so we wrapped that into immutable state so what is immutable state well so immutable state allows us to hold the state right it's just a wrapper that holds a state but most importantly these values are going to be able to send information to to send events in this case the compose function will observe this value so all we have to do now is say dot and get the value so it's a little bit more work a little bit of code but we're just going to say get the value of that mutable state okay and here too we're going to have to say that value like this and if we run this we should see [Music] the same thing but we've just changed the way we are creating these variables okay now you can see everything still works the same which is great now although everything works fine we can tap and you can see the numbers going up that's fine but the whole idea really is to make sure that we update this 100 here right we have a counter here that we want or text in this case that it must update as we tap and if you see all this clicking is happening inside of create circle composable so how do we then call that somewhere where we can then in this case be able to attach to this text here right meaning this money counter here we want to attach to this text so essentially do exactly what we did here like this was just testing we want to attach money counter to this text and so we can see then money going up how do we do that well the first thing we need to understand is that we'll have then to remove this state here outside of our create circle this is another concept called state hosting which means we are um hoisting it we are taking it up a level from where we are this day so i'm going to cut this and i'm going to call inside of my app of my app like this okay so we have a money counter and there it is but then of course this is not going to work here in our clickable because we have lost that how do we then make it so that we're able to still interact of course with our clickable right make sure that then this counter is still valid meaning that we can still click and change this value here because now we have this huge disconnect and you can see uh things are failing at this point so first what we need to do is in our circle create a circle here we're going to pass a few parameters so the first one is going to be money count like this it's going to be an int just a normal variable this is not going to work so what i'm going to do let's just for now comment all of that and let's just call it here let's copy this money count okay let's go ahead and say alt enter to remove the braces because we don't need those okay so we're moving things around here i'm just get rid of this and now i have an issue because we need to pass an initial value let's just say zero so that the preview still works okay so nothing works yet but at least we have something notice our clickable is not going to do anything but at least we know we have hosted our state up here okay but the next thing we need to do also here right we need to pass some sort of a callback so i'm going to say updated or update counter it's going to be a function remember we can pass functions as parameters which is really amazing the idea here is that we'll need to pass something into this counter this update money counter function what is it that we're going to be passing well we are going to pass an integer because it's going to be what we're going to be updating using to update in this case the counter and this will return nothing so it's going to say unit as such let's go ahead and close this down so i have more space okay again we have an issue here for now let's go ahead and comment this out we don't need to show a preview of this okay so there we go so now this update counter will expect what an int which is going to be the actual counter that means then if we go back to where this has been called that means we have to pass a few things if you hover over says no value passed for parameters update money counter you can see here expects money counter right but because we passed an integer also a default value it's not required but update money it is so that means then i'm going to pass my counter what do we call let's see counter money counter is going to be set to what well we're going to set to money counter we created at the top here say money money counter now so it happens that it so happens that i actually named them [Music] it so happens that i name both the parameter name the same name as our variable here our multiple state that's okay in this case i'm just going to have to go and say dot value because i need to get the value because remember now this is wrapped inside of a mutable state so we need to get the value the actual int okay now if you hover over again notice that we pass here this update money counter which expects which expects an integer also because is the last parameter that is a function right inside of a function that means we can actually treat this as a lambda which means i can just go outside and say braces curly braces like that and voila now you can see we have this int or it should say which is an integer which is going to be the number that's being updated so here then what i need to do is to of course update this money counter variable which is immutable state right each time we click we are going to receive that value right so here i'm going to say money counter i'm going to say that value it's going to be equal to the int we are getting plus one like this and now because we understand that this money counter here it's going to update its immutable state so it's listening to states i can change this to something like money counter that value like this and see what happens let's go ahead and run and there you have it the moment it starts it looks at the money counter it knows that the default value in this mutable state is zero if we put 10 here this would show here okay now let's see moment of truth if i tap nothing is happening what's going on it looks like we haven't done anything unclickable right we just comment things out and we still have this lock that's not what we want what do we want to happen here well here's the beauty we have this callback here that means then each time we click we're going to say update call this update money counter and what we're going to do we're going to pass inside here our money counter value right because that's going to be the value that's been incremented there that's an integer so let's go ahead and run this one once again so now if i tap voila you can see now says one and keeps growing as such and we still have this attached to tab we can just remove that that was for testing let's see we run again okay there we go now we tab c1 and it's going to go and increment there we go and even to make it better because we want to separate the concerns here what i can do in our circle we are passing of course my counter which is going to be set to our money counter which is immutable state there is a state here what i can do actually is as follow i can actually change this because i want to change the naming i can say for instance new value right and give it an arrow like this so now what i can do i can say our counter money counter that value is going to be set to our new value as such which means then the updating or the increasing of the money will happen inside of our update counter so i can say update counter plus one like this so now we have set everything up the way it's supposed to be and this var here looks like it's complaining you can always say alt or option enter it's going to say change this to val and we're going to do that okay so there we go so we've hosted the state to the calling the composable because my app is calling in this case this create circle and then what we're doing here is that for a circle we change a few things we add it we pass the money counter argument which is going to take care or it's going to track what's happening with our money counter there okay okay that value and then because we have the lambda in our create circle we have a function that that we call the update let's put this in a new line this update money counter and we're passing in so we call that every time the button is clicked we're going to call this update money counter we're going to pass the money counter whatever value we have here and add one to that that's exactly what's happened here so it's going to look at money counter is going to be zero at first we're going to be passing that value into this which in turn we're going to set that value to the new value we're getting which in this case we are updating by one and now my friends we have created a very simple application it does not a lot but it really shows us this concept of state which is very important but also shows us how do we hoist elevated state to the calling composable now why is it important to hoist the state the reason why we want to hoist this state from our main composable to the calling composable composable functions need to be stateless relatively stateless which means they should not hold the state right because we want them to be as flexible as possible at this point i can call this anywhere i want because it doesn't hold any state we don't have this state here holding us up right so whenever i call or whatever i call the create circle i'll have to pass in the money counter and the update money counter function there so we will delegate we'll send the state to the parent composable which will hold that state and that will be changing itself there and so this state is going to be changing and then it's going to be propagated down to our circle create circle which then is going to go ahead and update the money so there's a lot i threw at you here and i did take my time to explain this because i want to make sure you really get this concept again we will continue work with this but i had to go slowly because i really really really want you to get this concept and also remember this is just the beginning of our journey here so there will be a lot of opportunities for you to practice this as it is you can go ahead and practice this concept by creating for instance a counter different counters and so forth and see how this works in fact one of the things that you see that you can do you can now because we've hosted the state right it's here now we can do all sort of things with that state for instance we can say money counter that value is greater than 25 i want to show a text that says lots of money like this right because we have that state and it's easy for us to do such in a previous example we wouldn't be able to do that because the state was inside of our create circle now it's no longer there so we can do so all sort of things right so let's see if i keep tapping okay getting there lots of money so i hope this was helpful and i'll see you in the next video so in this section we did a lot of things the first thing we look at was the basics of compose project and function so that we can situate ourselves as we progress in our learning process here and of course we created a very simple money counter app which the main idea was to show you how things are constructed or how to put together a very simple application but give you the foundation of how compose works how composable functions work how you call composable functions inside of other composable functions so how to simply structure your compose applications okay and of course we look at modifiers which is a way of us to customize our compose widgets and there's so much you can do with modifiers and we'll continue obviously building upon this concept as we move forward in this course we talked about basics layouts surface which we said it is the main the most primitive traditional canvas that we can manipulate and use it to add other widgets on top box and column and so forth so we also learned that in compose you can make anything clickable meaning you can respond to a click event a tab event not only buttons receive click events but anything really can also receive a click event through modifiers and of course we talked about state and compose which is a very important topic because the whole idea in compose is to make sure that we dissociate this direct tinkering or updating of the state of widgets directly like using setters and so forth so state allows us to do all sort of things but mainly to decouple this dependency between the user interface and the logic but the main goal really is to have one source of truth in our project through states and with that we really dove into the imperative and declarative approach the differences in advantage of those so imperative meaning the older quote-unquote way of creating apps in android and we learned that the industry now is favoring more a declarative approach did the clarity approach you're declaring what you want to see on the screen and let data be the reactor data being the thing that will allow the functions in this case the composer functions to react and to describe themselves as they supposed to so the data is the ingredient if you will that makes this declarative approach even better we talked about state hosting again which is a way in which we need to remove the state from a composing function to the calling function that way that way we decouple this state with a composable making that composable function more reusable and easy to manage and of course we had to define this very important aspect of compose which is called recomposition composition is the process of calling your composable function again when inputs change which again is the whole idea behind a declarative approach and the beautiful composition is that when that happens we are only targeting or i should say the compose compiler is only targeting the widget or the composable function that needs that requisition that needs to be refreshed if you will anything else around it if it doesn't need to refresh itself it won't it just targets the one widget or two depending that needs to change if data changes which is amazing because now we are making sure that we don't run into memory issues because recompose or refreshing the whole screen every time something change it takes a lot of memory right a lot of computing power and so the way compose works with recomposition it makes it way easier and more memory efficient now one thing i have to say that these concepts this paradigm shift from imperative to declared approach of building applications it can be very daunting at first or at least it can be very hard to grasp not because the concepts are are hard to grasp but because it's a shift of paradigm it's a shift of way of thinking about building apps right so i encourage you to really take the time to watch the videos if you need to because remember this is video course which means you can watch as many times as you need and really if you hone in and understand this concept you're going to have a better time building compose apps because these concepts are the base of everything we're going to be learning now forward okay i'm very excited as you can tell and i'll see you in the next section so i hope you enjoyed this video where i showed you around check i composed and how to put together something an app in jetpack compose of course there's more to jetpack compose in fact if you want to learn more about jetpack compose i've actually put together a new course with 27 hours i think 27 hours 29 hours i should say of jetpack compose it's a full-fledged course you will learn everything that you need to know about compose but not only about compose i also have sections on on kotlin which is the programming language used in jetpack compose okay if you're interested in our course which i think you'll love it go ahead in the link below go ahead and just click on it and go and enroll in the course it's gonna be great for now thank you so much for your time i really appreciate your time and if you have any questions comments if you like this video thumbs up and share this video of course with your friends anybody that you think will benefit from all of this stuff all this content that i put out here so thank you so much for your time um well i'll see you next time
Info
Channel: Build Apps With Paulo
Views: 755
Rating: undefined out of 5
Keywords: #android12, android compose tutorial, kotlin tutorial, android studio, kotlin, room
Id: nQ5T2IJ1KYI
Channel Id: undefined
Length: 106min 12sec (6372 seconds)
Published: Tue Nov 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.