Jetpack Compose basics | Workshop

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everyone and welcome to this compose workshop in this session we're going to do some live coding and we're going to follow the compose basics codelab so if you want to follow along things make sure that you're using the latest version of android studio so that is arctic fox beta which was released the other day you can find the link to the collab in the description of this session if you've got questions around the collab please ask them using the q a system my colleagues madeline nick butcher nick roth and yesterday's good are ready to answer your questions okay so what is jetpack compose jetpack compose is our modern native ui toolkit for android it's intuitive it's powerful and it was built from scratch to accelerate development so it will let you write ui with much less code so in other words it's faster and easier so you can focus on building features and spend less time creating ui so currently just like a bose is in beta but fear not stable is around the corner it's coming in july okay so let's get started going hands-on with compose so i am in my android studio and in the welcome screen so i'm going to go to new project and here i'm going to select an empty compose activity click next let's name this compose basics and finish while the app is building let me tell you what you learn in this workshop you learn what composes how to build uis with compose how to manage state incomposable functions what are the data flow principles in compose how to animate your composables and finally how to theme your composables so uh during this codelab i'm also going to use some some functions from the kotlin standard library so i'm going to quickly add this dependency here right now so oh i won't have to do this later okay so uh let's explore a bit what was generated by the compose template so we have a ui theme with some color shape theme okay and a main activity so in the main activity we can see the oncreate function but then also two other functions annotated with ad composables what are these so these are composable functions so this is actually just a regular function that's annotated with act composable but this enables your function to call other composable functions within it this function will produce a piece of ui here so um this uh given this input given the name input it will display a text and then this text function is also a composable but this is coming from the from the compose library so with compose activities still remain the main entry point to an android application so in our project the main activity is the one that's going to be launched when the user starts the application but instead of using the usual set content view call we are we are using set content so we are no longer specifying an xml layout but rather using this set content method we can call composable functions to build our ui and then what we see here the compose basic theme is how we are able to style our composable functions but we're going to go a little bit later in theming in our workshop okay how does our app look like how do we know that so there are two ways to um to run the app so we can either want to see this we can either run the app in an emulator so pretty much like you normally would with any application or you can use previews in the design surface so to do this i'm going to go to split view and this should load our previews so previews are on uh to see a preview we're now waiting for the build and we're able to see it and we're also able to see the application in the emulator cool um so what are previews um so what we've done here is we've marked a composable function with at preview annotation so while doing this the android studio allows us to to see how the composable would look like you can have multiple previous in the same files or for different composables that are contained in that file but then you can also add multiple add previous annotation to one composable so for example let's say that i want to see how my composable looks like if i have a font scale of 1.5 f and the preview renders both of them so using a preview is great because you don't have to run the app and navigate to whatever screen you're working on you can just see it in your id i'm going to remove this for now just to have a simpler preview okay so let's go to the next step let's actually modify our ui and and build something so uh first um i'm going to set a different background for the grid tick so we can do this by wrapping our text inside a surface moving the text inside the surface and then i'm going to make the color of the surface yellow um so the components nested inside the surface will be drawn on top of that um of that background color so in the preview we're able to see how the text is drawn on top of the yellow surface okay now let's say that we want to add a padding to our greeting text well to do this we are going to use a modifier modifier parameters tell a ui element how to layout display or behave within their parent layout modifiers are just regular coupling objects but all compose elements ui elements like surface or text can accept this optional modifier parameter so for example to add a padding to our text i'm going to add a modifier which is modifier padding of 16dp and dp is a measurement the density pixels that i just imported and now we can see how the padding was added around our text so modifiers can be assigned to variables and they can be reused so for example i can define a modifier parameter to librating let's give a default value of modifier and then here i can use this modifier and build on top of it so you can train several modifiers one after the other but what's interesting actually is that modifiers the order of the modifier matters so let's say that we also want to add a background to our to our text so i'm going to use a another background modifier let's say color dots magenta right yellow and magenta should do an interesting should have an interesting combination so we can see how first the padding uh was added and only afterwards the background was set so if we switch the order of these two we can see how first the background is added only afterwards the padding is set so the result that we're getting is very different depending on the order of the modifiers okay this magenta is nice but let's keep it simple and let's remove it i'm also going to remove this modifier from here and also this yellow surface just get this greeting a little bit simpler for now okay um let's take a step back let's think about the applications that we're usually building chances are these are much more complex than just the text view on just the text on the screen so the more components you add to your ui the more levels of nesting you create which is normal not just like any other function in your code base but the problem is that this can affect the readability if a function becomes really large so what we should do is make small composables that are um easy to be reused so it's easy to build a library of ui elements used in your application so like this every composable can be responsible for one small part of the screen and can be edited independently so looking back at our code we can see how the greeting is actually defined outside the main activity class so this is actually a top level function so that's great because the more code we have outside an activity the more we can share and reuse okay let's let's refactor this code and let's make it even more reusable so let's create a composable function that contains the compose ui logic that's specific to this activity so i'm going to use the compose live template and you let's call it my app and then here i'm going to move the content and insert content i'm just going to call my app okay so this is this is one good step or the one first step in the right direction so the the good thing about the mayak the map composable is that it contains the configuration for the entire app it has the theme it has the surface that's great but now the surface only contains this greeting so this makes it very specific to this screen but what we want is to be able to reuse as much as possible so we want to be able to use this kind of configuration for other screens as well so we want actually this my app composable to be a container function so to do this we want to pass in the content that should be displayed in that surface so to do this i'm going to create a content parameter which is a function that returns unit that is a composable function so i'm returning unit here because as you see also from the greeting function um we don't return ui components but rather composables omit them okay and then inside the my app function i'm just going to call content okay let's uh here let's call the greeting and then in the preview let's also use the creasing okay so in the end what we have right now is actually equivalent to what we had before but the code right now is just much more flexible making container functions is a good practice that improves the readability and encourages code reuse okay let's go one step further with building our ui let's say that uh let's say that we want to show the greeting multiple times so of course we don't want to duplicate code right so let's say that we want to show the greeting two times one under the other separated by a divider so this would be our screen content so let's create a composable function that is called my screen content us because we want to show consecutive items or ui elements or ordered vertically placed vertically then i'm going to use a column here i'm going to add my greeting where i'm saying let's say android we said we want to have a divider and then another greeting that says there okay and then here in my app instead of calling greeting i'm going to call widespread content and similarly in the preview okay let's see yeah and now we can see how the two greetings were rendered one after the other so with composable functions well they can be called like any other functions in kotlin so we can use for loops if statements and more so um let's try this out right now we hard coded these two greetings but let's let's pass in uh a names uh parameter to the function so this would be a list.string um let's say this is a list of androids and there and then here in our column we can just do for name and names and then instead of passing in the greeting and i'm going to call this okay and that's it we've seen how we can easily use a floor inside a composable okay so we've actually done quite a lot of things already like we've used composable functions to produce pieces of ui hierarchy we used modifiers to tell a ui how to layout or display or behave inside its parent layout we created small composables that can be easily reused and then we were able to call composables like any other functions in kotlin so compose apps transform data into ui by calling composable functions so reacting to state changes is at the very heart of compose if your data changes then you recall these functions with new data creating an updated ui compose offers tools for observing changes in your apps data so it will automatically recall your functions so this process is called recompensation compose also looks at the data that is needed by an individual composable so that it only needs to recompose composables whose data has changed and then it can skip composing those that are not effective so for example let's say that i have a greeting of android so this composed of all where we are in this composable we're hard coding the input so compose creates a ui tree so and this greeting specifically is just added to that ui tree once and it will never change even if the body of my screen content gets recomposed but where does it change let's let's see an example where this changes let's say that we're creating a counter that keeps track of how many times the user has clicked the button so for that let's define a compatible function that's called counter and here we'll have a button and unclick and we display i've been clicked x times okay so how would we do this um so we need an internal step right we need to have a a way to hold the number of times the button was clicked so let's see how this would look like if we have an it so i'll define a bar counter that's zero and then here in the button click i'll do counter i'll increment the counter and then in the text i'm going to display the value of counter let's run the app and see and see what we get oh i should also add the counter to my screen content so we can see it okay so we see the button and i'm clicking on it but nothing happens so why is that like i have a vari variable why isn't it to modified so the thing is that using an ant is not enough but what we want is when the state changes for the ui to also change and compose gives us tools to make this automatic so we would use a by mythable state of function that we're initializing with zero okay and the imports that android studio tells me to add so as the text reads uh this value it will be automatically updated every time this variable changes but now compose would rerun this function every time there is a change and then we would always reinitialize our count to zero but what we want is our variable to survive recomposition well to do that we use remember this is actually what android studio also tells us to do to use remember and i'm going to put the mutable statement here so by using remember we we give memory to our function so now we can see that we can click the button multiple times and the state is updated but the state is internal to the counter so if we have multiple instances of of the counter then each copy will have its own state its own version of the state so you can see that even if i'm tapping on the first counter nothing happens with the second one so they're all uh this data is internal so we've just seen an example of how we can transform state so the counter uh into ui so how data flows in your application and where you hold that data ends up being really important in components okay so right now the counter is internal to um to our composable but what if we actually want to um to use the value of the account in other functions in other ui's so uh let's say that in my screen content whenever that's i know the button count click is higher than five we want to display a text something like uh loads account okay how would we do this because we don't have access right now to the to the counts so what we need to do is to move this internal state higher to the color of the function and this process of moving the state to the color is called state hoisting so how do we implement this so we introduce um as parameters to our counter composables to two parameters first the count that's that's just an n value and this count will be used to be displayed in the text and then we will also add a an update count function so a a function that tells us when the count is updated and what is that value so it will have a an end parameter which is the new updated count and return unit and then in our button click i'm going to call update count with the count value plus one okay and then we said that we're moving the state higher to the to the color of counter so i'm moving um let's call this counter state i'm moving this counter state uh in my screen content and then in counter our counts is going to be the counter state and then in update count we have the new count and then we're going to assign the counter state the new account then we're going to use this counter state to decide whether we should display or not the text so now i love to count that's right so making state hostable avoids duplicating state and introducing bugs it helps reuse composables and it just makes composable substantially easier to test of course state that is not interesting to a composable color can be internal so for example in a scholar the scholar state position can be exposed but maybe the maximum position can be something that's held internally so the source of truth belongs to whoever con creates and controls that state okay so uh what did we do so far we looked at how state works in compose and how to use remember and mutable state up and why it's important to hoist the state when needed okay um let's build some more ui let's uh let's update our ui and um so so far what we've done is we looked at how we can place items in our vertical switch sequence but in the same way we can use row to place the items horizontally but now let's say that we want to put this button at the at the bottom of the screen and then we can lift the list that we have here to expand as much as possible um but still remaining at the top so what we want is to have some items flexible so they occupy a portion of the screen so to do that i'm going to wrap this for into a column and i'm going to move this content here and to make this content flexible i'm going to use a modifier and that is the weight modifier i'm giving it 1f so this means that this column is flexible that it can expand um it can take as much space as it as it wants but then the rest of the content is inflexible so we also want to make sure that the column is going to fill the entire size of the screen so i'm going to add another modifier let's modify it up till uh max height let's see if we can already see this in the preview but also run the app on the emulator and see how this looks yeah we can already see in the preview that uh the the list is at the at the top and then the button is at the bottom okay now let's make the names list a little bit more realistic right we don't want to just use a four uh we've just displayed two items but how do we display thousands of items well uh before we do that let's uh before we change that list item let's extract the names column to a dedicated composable so i'm just going to create a another composable let's call it name names list and then i'm just going to move here the column displaying the the content i'm going to pass in the names so it's a list of string and then i'm going to pass in also the modifier so like this by passing in the modifier it means that i'm allowing the color to decide where this names list should be positioned how it should be positioned and then here i'm going to call names lists with names and modifier i still want the contents of this composable to be flexible so i'm still going to use um the weight modifier okay and now let's change the list we don't want just two elements let's make it a list of 1000 elements and then every element of the list should say like hello androids and let's see the account as well let's run this on the emulator let's see how it looks like okay so we can see our list but now i'm trying to scroll but i can't but that's because column isn't scrollable by default but to do that to make the list the column scroll we can use a lazy column so i'm going to replace this with a lazy column so a lazy column renders only the the visible items on screen and it allows performance gains when rendering a big list so this is equivalent to uh to recycler view in android views so what do we have with lazy columns so we're past in lazy column we can provide the items to be displayed so items here is our names and then i had to import it but then here what we want we define is what should be displayed for every item what is the corresponding ui for every item in this in this list then if we run it should be able to scroll yes we're able to scroll yeah looking at this i don't know it's just amazing seeing that we only had to write four lines of code to implement something that with views with recyclerview would have taken so much code you know you have to implement the recyclerview the adapter the viewholders and so on you know compose ends up being so concise and easy to use okay so lazy column doesn't recycle these children like recyclerview but rather what it does it emits new composables as you scroll through and it is still performant because emitting composables is relatively cheap to constructing android views okay so um we've seen how to use flexible layouts and how to display lists let's uh let's see how we can animate how we can add some animation to our ui so what should we do let's uh let's change the background color of a list item once we click on it so of course we want to animate from one current value to a different uh to a different value so because we need to know once we selected an element we would need to create a new state we need to introduce a state that tells us whether an item is selected or not so in the greeting i'm going to create a new state that's called it's selected and we're going to use the same uh remember mutable state of that we've used before with a default value of false so we need to know when a text is selected and when we when we click on the text and to do that we can use a google modifier because the order matters i'm going to put the clickable modifier before the panning so i have some more space to click on and uh what should happen whenever we're clicking on it then it's selected so elected it should be toggled right so the not is selected okay so now we know when our text is selected or not uh now let's set the color so this means that we will have a target color and if the text is selected then we should have i don't know color dot red otherwise we should be displaying color dot transparent so keeping the same the same color um that we have right now okay uh and then we want to set this as the background for the item so we've done we're doing what we did at the beginning of the workshop which is set the color of the surface to be target color and i'm going to move this here okay let's see how it works so far okay so now we can see how the color changes but this is not what we want right we want to be able to animate this to make this a nice transition between this transparent state to uh to the red background we have well to do this we use animate color as state where the target value is defined by our f and i'm also going to use a delegate here without the delegate i would have to do targetcolor.value and the delegate just makes it easier to use okay now let's see what changes so what animate color does is it takes a color as a parameter it saves it and then it generates the intermediate is required to display an animated transition between a previous set of colors to the new one so if i'm clicking on an item we see that there is some animation i think the animation is a bit too fast for our our live stream let's uh let's slow this down so anyway color state also allows us to to define an animation spec so um the compose offers different types of animations from springs to repeating animations um for today let's just use a tween because that's uh the simplest one that allows us to set the duration so we can see it so for what we want it should be enough okay and we can see how it changes i'm sorry for all the designers out there watching this this is not the prettiest one but look how nice it animates and looking at the code like this was all the code needed to write an animation that's that's pretty cool like with views that would have taken us a little bit to to write okay um yeah so what we've done here is we kind of hardcoded we hardcoded this color and that's not really something that we want right we want to use something that's specific to the application theme so for example we would want to use like this kind of a purple that we have at the bottom so this purple or the color of the divider uh all of these are colors that come from the application so this is how we define the theme so we've we have a composable compose basic theme composable that wraps the content that we want to display on the screen so this compose basics part actually it's generated based on the name of the of your application so it will change them depending on what how you named your app but if i look inside i can see that under the hood this is using material theme so that's because compose offers an implementation of the material design system so all components follow material styling so we see that we have a composable material theme where we're passing in colors typography shapes so the colors typography and shapes these are all elements that were defined here the colors the shapes and then in the type the typography so these are all elements that you can change so you can give that unique feel to your application and then what we've done here is we defined that color palette both for uh dark and light mode so for example here we're setting to use purple 500 if i would change this to color dot red for example i should be able to see how my button also changes to right yeah okay i'll revert this back to purple just to keep it nice okay so back to our application we said that we want we sh we don't want to have this uh as color we want to use an app theme but um how do we get that so you should use elements from the material theme directly so i'm going to go for material theme colors and primary so you should do this rather than specifying the colors directly because like this darkening is automatically supported and you don't need to define colors all over your code so let's see how this looks like then when we click on an item we see how the color changes but also the text color changes so why is this well because the material surface understands that we use the primary color from the theme then it automatically sets the text to use on primary color which is also defined in the theme and then if we switch to dark theme we can see how the right colors are again used so all of this is something that we got out of the box by just using the material theme from uh from compose oh okay we looked at a lot of things in this codelab we looked at what composable functions are how we can layout composables we've displayed lists using lazy column we've animated we've animated our ui using things like animate color as states we saw how theming works we've done a lot and i'm hoping that this is uh something that i know makes me more curious to try and compose a little bit more so if you want to learn more about compose go to developer.android.com jetpack slash compose here you can find a lot of documentation uh following uh about compose following a lot of topics from state architecture animation um theming to accessibility and testing including interrupt interoperability and then check out the sample apps to see a lot of examples of how compose works in practice and then check out our curated pathway of collabs and and the videos to find out more about compose and actually what we've done today was this jetpack compose basics that's all i had for you for today so thank you for joining and happy composing i can't wait to see what you build the compost
Info
Channel: Android Developers
Views: 34,780
Rating: 4.8563886 out of 5
Keywords: purpose: Educate, type: Conference Talk (Full production), pr_pr: Google I/O, How to create an app in Jetpack Compose, How to create an app, Jetpack Compose tutorial, Basics Jetpack Compose tutorial, Jetpack Compose UI toolkit, UI development Android Developer News, Android Developers, Android Dev, Google Wear Apps, #GoogleIO, Google I/O, Google IO, Google developer conference, Google announcement, Google conference, Google, android, Android Jetpack, Android Studio
Id: qvDo0SKR8-k
Channel Id: undefined
Length: 39min 55sec (2395 seconds)
Published: Mon May 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.