Global CSS version='1.0' encoding='UTF-8' ? droidcon News droidcon Online 2020 Share Tweet Become A Composer By Brian Gardner droidcon Online 2020 Jetpack Series Part 1 of 3 Transcript English 00:00 hello everyone my name is Brian Gardner 00:03 I am a developer and instructor at big 00:06 nerd ranch and today I get to talk about 00:08 jetpack compose so as Marcus was 00:11 mentioning compose is still pretty rough 00:17 around the edges let's call it it is a 00:20 dev release currently so pre-alpha even 00:23 so things are changing quite a bit but 00:27 overall I like it it's a really fun way 00:30 to build user interfaces for Android so 00:33 the goal for this talk suppose I could 00:37 present is I'm basically going to try to 00:40 recreate the ListView from Gmail so 00:46 there will be an individual list item 00:49 for each email I'll try to add a toolbar 00:51 at the top floating action button as 00:54 well as the navigation drawer on the 00:56 side so I think compose is one of those 00:59 things that it really is a lot better to 01:01 kind of see it worked or see an example 01:04 work through so let's do that 01:09 I have a little screenshot of the main 01:14 screen that I'm trying to build here and 01:16 I have my studio open so the first thing 01:20 that you're going to need is you're 01:22 going to need a specific version of 01:23 Android studio so Android studio 4.1 is 01:28 the one you're going to want this is 01:30 currently in Canary but it's the only 01:32 version that has the actual compose 01:34 tooling the 4.0 beta doesn't have it 3.6 01:38 doesn't have it so make sure you get 01:39 studio 4.1 the next thing you're going 01:43 to need is some various dependencies so 01:45 inside of your android block 01:49 you can add these compose options 01:52 this is just a Kotlin compiler version 01:55 that you're gonna need in order to get 01:57 composed working you run into some weird 01:60 issues if you don't have this compiler 02:01 version specified so you want that and 02:04 then there's a Colin compiler extension 02:06 version as well which you can see this 02:09 is where the dev release comes in what 02:14 you'll also need is the actual 02:17 dependencies themselves so there are 02:19 sort of two versions that you'll need 02:22 one is the composed compiler and runtime 02:25 so this just makes sure that compose can 02:28 build and actually run when you're using 02:31 it and the second is the UI libraries so 02:36 this actually includes like the text the 02:39 buttons stuff like that so that's mostly 02:42 what you'll be using when you're 02:43 actually building out your application 02:45 whereas the compiler and runtime just 02:47 make sure everything actually works so 02:51 in the interest of time this will be a 02:53 little bit like a cooking show it's a 02:56 little bit of stuff made fresh and a 02:58 good bit of stuff I've prepared earlier 02:60 so one of the things I've prepared 03:02 earlier is a data class that represents 03:05 an email so I have things like the 03:08 sender text if the email is important 03:11 which shows this little icon over here 03:13 the receipt time subject text body text 03:17 stuff like that so that just prevents me 03:20 from having to build that out most of my 03:23 time is going to be spent building the 03:25 actual email view itself so the the 03:28 individual row item is what I'm mostly 03:30 going to be focusing on so with compose 03:34 there's no XML thankfully everything is 03:38 going to be built inside of Kotlin so 03:41 when you want to create something that 03:43 shows on the screen you need to create a 03:45 function that's annotated with the @ 03:47 composable annotation this tells compose 03:50 hey this thing is actually a view that 03:53 needs to get displayed on the screen so 03:56 in this case I just have a top-level 03:58 email view which will take in my email 03:60 and as I go through I'll actually build 04:02 this thing 04:03 out now with compose I really like to 04:07 start sort of bottom-up you start it 04:09 you're kind of most basic view 04:11 components and build your way up 04:13 so I'll start there so starting at the 04:17 top we could start with the sender text 04:19 right here so when you want to display 04:24 text in compose there's a text function 04:27 so you just say hey I have some text and 04:30 I can set the text to my sender so that 04:36 will actually render whatever text you 04:38 send in now if I want to actually see 04:42 this working there's a couple ways I can 04:44 do this 04:45 one I could add this into my activity 04:47 throw my sender in there run it display 04:51 it in an emulator but that's a little 04:53 bit slow but what you can do instead is 04:56 there is a preview option so you can 05:00 create a preview function annotated with 05:03 app preview and at composable and this 05:07 will render this nice little preview 05:09 pane over here on the right-hand side of 05:11 studio so right now I'm just rendering 05:14 my email view with a bogus email but 05:18 there's nothing in my email view so 05:19 nothing is rendering but if I did want 05:21 to render something I could just say hey 05:24 render my sender text you do have to 05:28 build every time to get the preview to 05:30 actually work hopefully this shouldn't 05:33 take too long as I was working on this a 05:36 little bit earlier but there you go 05:38 so you can say hey my email view preview 05:41 is getting rendered and I have some text 05:43 getting displayed that's great but say 05:48 what if I wanted to modify this text 05:50 what if the default style doesn't work 05:52 well the good thing is the API for 05:55 compose is very fluent so it's has a lot 06:00 of niceties so it's like hey I want a 06:02 style I can provide a text style the 06:06 text style class has pretty much 06:08 everything you would need to modify your 06:10 text color font size letter spacing text 06:14 decoration like I said there's a lot of 06:17 I'm not gonna go through everything here 06:19 I'm just gonna maybe tweak the color of 06:21 it and maybe the font size maybe say 06:26 twenty sp so color here is a specific 06:32 object you can pass in a hex value if 06:34 you want and it'll configure that 06:37 appropriately or you can just use one of 06:39 these defaults and in my case most of 06:43 the defaults are going to work so I just 06:45 used that the sizing here is actually 06:49 pretty nice so they provided this SP 06:52 extension function on I think doubles in 06:56 maybe number but this basically will 06:59 convert this to the style and are the 07:01 scale independent pixels so it'll 07:04 respect both the density of the screen 07:07 and the user's accessibility settings 07:10 now if i refresh this the preview isn't 07:14 actually going to change because the 07:17 color is the same and the text size it's 07:19 getting scaled anyways so you're not 07:22 really gonna see much difference but 07:23 i've messed with this before and 20 07:25 pixels seemed alright so what I can do 07:29 next is I need to provide my important 07:31 icon so this one I already added a 07:36 vector asset for this so to display any 07:40 kind of resource you're going to want to 07:42 use the icon function you just provide 07:45 an asset and there's a vector resource 07:48 function you can use to load a vector 07:50 asset so this is my important icon go 07:57 back to code so this will just load this 07:59 asset and put it in something that can 08:02 load an icon so what I can do next is 08:05 the sender text and the icon need to be 08:09 displayed next to each other along with 08:11 the receipt time way over here on the 08:14 right so what I can do 08:17 is I need to create another composable 08:20 function to basically contain these 08:21 things I could put everything in my 08:24 email view but that might make things a 08:26 little messy so I can create another 08:28 composable function maybe call it email 08:31 header 08:35 pass in the string and then this is 08:39 where I'll actually configure the 08:40 important icon sender text and the 08:43 receipt time now everything needs to be 08:46 displayed in a row here and fortunately 08:48 there's a function called row so I can 08:52 just say hey I just want my sender with 08:56 my sender string and in front of that I 08:60 need my important icon so I can then 09:05 update this to be my email header email 09:10 sender and then if i refresh the preview 09:15 it should show the important button in 09:18 front of my text which it does there's a 09:23 couple things wrong here number one the 09:25 color is wrong number two the icon is 09:28 actually a little bit above the text so 09:32 I can modify the color of an icon so 09:36 there's a tint property which is really 09:38 nice 09:40 I could try yellow for this it doesn't 09:42 quite look right so I did some 09:44 experimenting and just grabbed the color 09:46 for the actual gold 09:48 I think it's ffff D D six six three that 09:52 should tint the icon so I'll just go 09:55 ahead and run that and then my email 09:59 header I need everything to kind of be 10:01 aligned in the row so there's a vertical 10:04 gravity property that you can provide 10:07 and say hey please Center all of the 10:11 contents vertically for me so that 10:15 should kind of move everything a little 10:17 bit the icon will move down just a 10:18 little bit to be in line with the sender 10:20 text so the next thing I need is the 10:25 receipt time there's nothing super 10:27 interesting about the receipt time so I 10:29 went ahead and implemented this already 10:31 this just takes in the time that I want 10:34 it to display as a string the reason 10:36 this is a string and not like a date or 10:38 a long or something is these are kind of 10:41 my lowest level view components so they 10:45 should be as dumb as possible 10:47 they shouldn't do any sort of formatting 10:49 or anything like that that should be 10:51 reserved for like a view model or a 10:53 presenter by the time your data hits the 10:56 view layer it should be ready to display 10:58 immediately so I'm just assuming that 11:02 will be formatted for me and then I said 11:04 yeah hey show me some text and then give 11:07 it a style if I want to add this to my 11:11 row I can just add the receipts time 11:16 whoo it's my header so I actually need 11:20 to pass in the receipt time to my header 11:23 get that modify 11:28 and here we go then I need to past and 11:31 the receipt time 11:35 space that out a little bit it's a 11:37 little easier to see rebuild that and 11:39 that should display the receipt time 11:41 next to my sender text which it does but 11:46 everything's a little bit squished 11:47 together so there's a couple of reasons 11:50 for this number one 11:51 the RO assumes that it only is kind of a 11:54 wrap content width so it's kind of 11:56 squishing everything together so what 11:59 you can do to modify that is there's a 12:02 modifier argument on pretty much every 12:06 composable function so modifiers are how 12:09 you add things like padding setting the 12:13 size of something filling up the space 12:15 so that's what I'm gonna do here so I 12:18 could say hey please have this row fill 12:20 up the max width so it'll basically fill 12:23 up its parents so if i refresh the 12:26 preview will see that the row does in 12:28 fact fill up all the space 12:29 who not height there we go 12:33 fill up the width 12:36 that'll fill up the max-width but we 12:37 still kind of have the same problem in 12:39 that the receipt time is still smooshed 12:41 up against the sender text and how we 12:46 fix this is we need to provide a 12:48 modifier to the sender to tell it to 12:50 take up the full width or the remaining 12:53 space so I'm going to need another 12:56 parameter here and inside of the row 12:59 this lambda basically is all of the 13:02 child views you want inside of your row 13:04 but specifically this is a row scope 13:06 which you can kind of see from this hint 13:08 here now the row scope defines some 13:11 custom modifiers one of which is a 13:14 weight 13:15 so this basically says hey sender please 13:18 take up whatever remaining space is left 13:20 I need to provide the actual modifier 13:23 parameter here and I want to go ahead 13:26 and provide a default just in case 13:29 so my sender doesn't have to be used 13:31 from a row if it doesn't need to be so 13:36 providing this weight to the sender will 13:38 basically force it to take up whatever 13:40 remaining space is left if it works I 13:43 need actually apply the modifier that 13:45 would help there we go 13:50 so once the modifier is applied to the 13:52 sender the text will basically expand 13:54 out as far as it can and push the 13:57 receipt time all the way over to the 13:58 right which is great so that's kind of 14:01 the email header next I'm going to focus 14:04 on building out the actual email view 14:06 itself so the next thing is the header 14:10 is stacked on top of the subject and 14:12 body text so in the header 14:15 I used a row to stack things as a row 14:18 fortunately there's also a column that I 14:21 can use to stack things vertically so we 14:25 say hey have an email header pass in a 14:28 subject and a body 14:35 now these like the receipt text there's 14:38 nothing super exciting going on here 14:40 it's just declaring a text setting that 14:43 setting a font size and a color the body 14:46 is actually a carbon copy of the subject 14:48 so nothing too much to look into there 14:53 but you get to see the preview refresh 14:57 and then actually see it displayed in a 14:59 column so we have things kind of getting 15:01 the email views coming together at this 15:04 point next is we need the little star to 15:08 show up and if you look closely the star 15:11 is actually in a row with the subject 15:14 and body text because they're both 15:16 ellipse sized so the subject and body 15:20 are in a column because they're vertical 15:22 and then that is inside of a row so that 15:25 the star can be in the right place so I 15:28 can add this stuff so say hey row 15:31 add a column well dump the subject and 15:35 body text into here and then I need a 15:39 star to go in the row as well so I have 15:44 that so say email that starred the star 15:49 at this point is very similar to the 15:51 important icon it's loading a vector 15:55 resource it's getting tinted the only 15:58 difference is I'm modifying the color of 16:00 the star based on if the email has been 16:03 starred or not so I can just use this if 16:06 logic thank Scotland for not having me 16:09 set that twice but once I run the star 16:14 you see kind of a similar thing so the 16:16 star is smooshed over up against the 16:20 subject and body text because they are 16:23 only taking up as much space as they 16:25 need so I need to go back and have the 16:28 column take up plenty of space so we'll 16:30 use that modify our weight trick and 16:35 another thing is the star it needs to be 16:37 in the bottom over here so in a similar 16:40 trick we can use the actually the 16:43 vertical alignment or gravity say align 16:48 the start 16:49 the bottom or align the row to the 16:51 bottom rather the subject and body are 16:54 not going to be impacted by that because 16:55 they're already taking up the full 16:57 height but the star will get pushed down 16:59 to the bottom now another thing that 17:02 needs to happen is the star needs to be 17:05 clickable because right now it's not 17:07 responding to any kind of click events 17:09 so what I can do is the star needs to 17:15 basically take in a listener and fire 17:18 off the listener when it gets clicked on 17:21 so we can just say like add an on click 17:25 lambda no parameters doesn't return 17:30 anything this is your typical click 17:33 listener here and then you can wrap your 17:37 icon in an icon button 17:55 let's name that maybe it's just made 18:03 you 18:08 there we go so we basically just say hey 18:12 the button adds a clickable interface 18:15 around our icon so it'll fire the click 18:18 listener whenever it gets tapped so that 18:21 I then need to provide a click listener 18:23 here this brings up another question my 18:28 email currently is immutable because 18:31 it's a data class but everything is a 18:32 valve so I can't set any of this data so 18:37 what if I need to there's a couple ways 18:40 of dealing with state in compose one way 18:42 is you can update your property to of 18:46 our if you need the setter and then say 18:48 hey this is a model so you add the model 18:51 annotation what this does is whenever a 18:55 composable function takes in a model 18:59 anytime it accesses the properties of 19:02 that model it is registered to observe 19:05 changes to those properties so since i'm 19:07 passing in the starred property my email 19:11 view will update if the property changes 19:17 so what I can do is I actually made a 19:24 property here so what I can do instead 19:27 this is a better example so instead of 19:31 an icon button what you can do is 19:33 there's a toggleable 19:35 that you can do so instead of just 19:38 responding to a click toggleable is 19:40 basically a click with a state so we 19:43 could say it needs the initial value and 19:47 there's a non value change function this 19:51 is different because on value change 19:53 requires a boolean so this is the flag 19:55 on and off so we'll just update that so 20:00 now our star can modify its color based 20:03 on the starred the on star click and we 20:07 should be able to react to it this is 20:10 going to be mad because I need to finish 20:11 this but I can update my email and this 20:17 should be happy 20:20 so I can try to run the app over here on 20:23 an emulator so he gets my little email 20:27 list and when I click on the star it 20:29 updates which is cool it does work 20:32 another option you have if you don't 20:35 want a mutable class here you can keep 20:39 everything vowels but you would need to 20:42 wrap your property in something called a 20:46 mutable state 20:51 so this is basically saying hey this is 20:52 my state instead of the email itself and 20:56 then I can pull out the email from the 20:60 state now accessing the value of a state 21:03 works similarly to your model any 21:05 changes made to the state are going to 21:08 cause your view to recompose it's just a 21:11 little bit more complex I'll need a new 21:13 email fortunately since I'm using the 21:19 data class I can just copy it and over 21:24 at the fields I want and then I can set 21:26 the value like so that will cause it to 21:31 update my email preview needs an update 21:35 because it's still expecting an email so 21:38 if you need a state there's a mutable 21:42 state of function and that'll basically 21:46 wrap your model object in a state you 21:49 pass that along I'll need this same 21:51 logic in my activity to actually run the 21:54 thing so I'm now passing in a state 21:58 instead of the email itself 22:02 and I can still update the star so it's 22:06 still responding to clicks and it's 22:08 still updating my view state I like this 22:11 a little bit more just because it makes 22:14 me be very explicit about state updates 22:18 instead of having like a mutable class 22:20 but that's kind of a personal preference 22:22 right now so in the interest of time I 22:27 think we'll keep this about where it is 22:30 I'll actually just add some padding 22:35 let's do 16 dips so that will just add 22:41 some padding around my email view just 22:44 to be a little bit more material and 22:45 make it look a little bit nicer so there 22:49 we go got some padding so that's the 22:52 email view so it's fairly easy to build 22:54 all of these things from the bottom up 22:56 if you want to display a list I'm gonna 22:60 make another composable function called 23:02 email list that takes in a list of 23:05 e-mails and if y'all are familiar with 23:08 Android you probably know about 23:09 recyclerview and it's got a fair bit of 23:12 pieces that you need to kind of put 23:14 together 23:14 fortunately making a list in compose is 23:16 a lot easier you just use this adapter 23:19 list thing pass in your list of items 23:22 and then you just provide this lambda 23:25 which is the child it passes in each 23:30 item that needs to basically render on 23:32 the screen so it's similar to recycler 23:35 view it'll only request the items it 23:36 actually needs to display alp make a 23:40 state and then I can return the email 23:47 view so recycler view would 23:52 we'll be a lot more code in this case 23:54 it's four lines of code I can go over to 23:57 my main activity I have a little 23:60 function to generate my list of emails 24:06 let's see we have a list so I get my 24:13 email list I'll create a mutable state 24:20 and then I'll do the email lists 24:24 actually I don't need a state here I 24:26 just need the list makes that a little 24:28 bit easier and I can run the app and it 24:31 will actually show the list there we go 24:36 so we have the list here performance not 24:40 great if I'm honest it's fairly clunky 24:43 and it it's a little slow so that's one 24:46 issue another issue is that the the 24:50 state updates do not currently work with 24:53 adapter lists so that's that's a really 24:55 big issue I've tried to fix this by 24:58 moving the state up to the email list 24:60 and then having the email list recompose 25:02 but that didn't work either 25:03 so there's currently a bug ticket open 25:06 for this and the compose folks are 25:09 working on it so hopefully soon it'll be 25:12 good but it is what it is for now 25:19 so next I want at bar up at the top so I 25:23 just have an email app bar composable 25:25 the component you're gonna want to use 25:27 is the top app bar there's also a bottom 25:30 app bar if you want bottom navigation 25:32 you just need to provide things like a 25:34 title navigation icon if you want it 25:37 actions if you need those 25:39 so maybe my text is I don't know foe 25:43 mail because it's some fake email my 25:46 navigation icon I can use an icon button 25:49 for this one wrap this in an icon vector 25:57 assets and we'll just leave the actions 26:03 out for now so this will basically make 26:06 a toolbar for the top of your app it'll 26:09 provide your little navigation icon on 26:11 the left the title right next to it 26:13 when you want to add these things all 26:16 together you could try and like make it 26:19 yourself like put everything in a column 26:21 and do all that but fortunately there's 26:24 a better way so typically what you'll 26:26 want to do is you want to make a 26:28 composable function specifically for 26:30 that screen so in this case I have an 26:32 email list screen composable takes in my 26:36 list of e-mails takes in some navigation 26:38 items which I'll get to in a minute but 26:41 you're going to use a scaffold now the 26:43 scaffold is the thing that kind of puts 26:45 everything together so you can provide 26:48 your app bar in the top app bar property 26:51 and then the last lambda is the body so 26:54 this is just whatever you need to 26:57 display in the application so if I 27:01 update my app to do the screen I'll pass 27:05 in the list and I also have a function 27:07 to generate navigation just so that 27:09 works this will show you the top app bar 27:12 at the top of the screen 27:16 so you got your toolbar you can modify 27:19 the app bar however you want you can 27:22 provide like custom views inside for the 27:25 text and everything so it's really up to 27:28 you what you want to do with it 27:31 scaffold has a lot of other stuff that 27:33 you can do most notably is the 27:35 navigation drawer so this is a rather 27:40 large class which is all for my email 27:44 navigation so it uses an adapter list it 27:48 has a sealed class to represent the 27:50 different item types 27:51 it sort of switches across those and 27:54 returns the different composable 27:56 functions that are needed for that I 27:59 have a preview in here so I can actually 28:01 show you what that will look like so 28:03 this is at the actual preview that will 28:05 get displayed I have a link to all this 28:08 so I can post everything but in your 28:12 scaffold 28:15 come on 28:20 you pass in some drawer content so this 28:24 is where you want your email navigation 28:27 pass in the nav items and one other 28:31 thing you're going to need is you're 28:33 going to need some state 28:43 so there's a different way to make state 28:45 so you can use this state lamda this is 28:47 a way of a shorthand way of making a 28:49 mutable state but the scaffold 28:53 specifically needs a scaffold state so 28:56 this is like is the drawer open or 28:58 closed and can you use gestures to open 29:03 the drawer so so far we have gestures 29:06 enabled and we just need to pass this to 29:10 the scaffolds now this state what it 29:16 does that's different from before is it 29:18 not only returns the state itself but it 29:20 returns a listener function so you can 29:23 use that kind of as an easy way of 29:25 updating but I should be able to use my 29:29 gesture to open the drawer it goes up 29:32 and down so looks good swipe it closed 29:37 not gonna deal with the nav icon quite 29:41 yet check out the code if you want to 29:43 see how that works I think the last 29:46 thing I wanted to show is probably 29:48 everybody's favorite material button 29:50 which is the floating action button so 29:53 there's a floating action button class 29:55 you can use takes an onclicklistener you 29:59 can throw an icon in it and it works you 30:02 can also use text if you want or 30:03 realistically any composable you might 30:06 just look a little bit weird if it's 30:07 like too large or something but all this 30:10 really does is give you the style of a 30:12 floating action button it grabs the 30:14 primary color from your theme makes it 30:17 circular and stuff like that when you 30:21 want to use it you just add the floating 30:24 action button 30:26 say new email button not gonna respond 30:30 to clicks just yet but this will add it 30:33 to the scaffold 30:34 it'll position it in the bottom right of 30:37 the screen and it gets you little ripple 30:42 animations there's also a position if 30:44 you want which one is it so there's a 30:50 the scaffold has a fab position you can 30:52 Center it if you want if that's what 30:55 your design works with so it'll just go 30:59 right there 31:00 there's also Center docked and undocked 31:03 so the scaffold also will work with a 31:06 bottom navigation and the dock will 31:09 basically like cut out the bottom 31:11 navigation for the floating action 31:14 button so if you want that in your 31:16 design it's pretty much included by 31:19 default in jetpack compose so that is 31:26 pretty much my demo let me see if you do 31:31 want the code for this 31:34 I have a bitly link here just jet back - 31:37 compose - webinar this will link you to 31:40 the github repo where the code is I 31:43 included a little bit of information 31:45 about myself as well as a bunch of links 31:48 for if you're interested in learning 31:49 more about jetpack compose one great 31:53 resource is there the Kotlin lang slack 31:56 if you're in there there's a compose 31:57 channel which is great there's some 31:59 Google folks in there so it's really 32:01 easy to get feedback like see what's new 32:04 what's working and they are very open to 32:07 bug tickets so if you find bugs please 32:09 report them next about me so again I'm 32:16 Brian Gardner I you can follow me on 32:20 Twitter if you like or check out my 32:22 website I've been doing a blog series 32:24 about jetpack compose I think there's 32:26 about 10 articles currently so if you 32:29 want a little bit more in-depth 32:30 information you can check those out also 32:33 again I work for big nerd ranch we do 32:36 consulting Android consulting iOS 32:38 consulting a lot of y'all probably 32:40 no us from our books I'm actually the 32:44 co-author on the fourth edition Android 32:47 programming guide so check that out 32:49 there's a lot of Jetpack goodness in 32:51 there and we teach classes as well so 32:54 hit us up if you're interested but 32:57 thanks for watching 32:60 Brian fantastic job thank you so much 33:02 for being here with us today it was 33:05 really exciting to see that in action 33:07 and and the way you presented that I'm 33:10 pretty sure if anybody's like me they 33:11 were pretty much glued to the screen the 33:12 entire time loved it thank you so much 33:15 for doing that you're about to play 33:17 question roulette as well and so we've 33:20 got Olli showing the screen of the most 33:22 popular questions and so I'm gonna let 33:24 you fire away on that yeah so top one 33:27 what have you found to be the benefits 33:29 of composed versus XML I think the 33:32 biggest benefit is XML is like I'm not a 33:36 big fan like it works don't get me wrong 33:38 I tried unko when it came out with like 33:41 JSON style stuff and it wasn't great I 33:45 like being able to have like 33:47 autocomplete in there you can easily 33:50 check the documentation for like the 33:53 text component say you can see all right 33:55 what exactly are all of the properties 33:57 that this thing has I don't have to go 33:59 to developer.android.com and look up the 34:02 documentation it's just a very fluent 34:06 interface I like it a lot more than XML 34:08 I think it's a lot cleaner 34:10 yes you're gonna have a lot more Kotlin 34:12 code in there because you're gonna have 34:14 to create all of your views in Kotlin 34:18 but I think it's kind of worth it 34:20 because you're you have you're gaining 34:22 Kotlin code but you're losing XML so I'm 34:26 a fan let's see mobile development is 34:29 shifting to declarative you eyes flutter 34:31 swift UI and compose how much sure do 34:33 you see compose let's say in one year I 34:37 don't see it being release or 34:39 production-ready in one year maybe beta 34:43 if we're lucky I'm hoping it goes alpha 34:47 a little bit later this year at least 34:50 just out of dev so things are a little 34:52 bit more stable 34:54 but I say we get beta next year maybe 34:57 release by like Android dev summit next 34:60 year fingers crossed 35:03 I dream one day we can use compose 35:06 alongside Swift UI to build 35:07 cross-platform mobile apps using Kotlin 35:10 multi-platform do you think this day 35:11 will come yes I definitely do the nice 35:15 thing about compose is that it's open 35:17 source and you can basically look at all 35:20 the commits that they're doing to the 35:22 project in sort of real-time one recent 35:25 commit they were specifically adding 35:28 functionality for desktop UI s so I 35:33 don't think there's a reason to do that 35:34 if they're not targeting some sort of 35:36 multi-platform so I have a gut feeling 35:40 that compose along with multi-platform 35:42 Kotlin multi-platform will kind of be a 35:45 sort of cross-platform II way to build 35:48 applications best live coding demo thank 35:53 you very much I have was super nervous 35:55 about this I haven't really done live 35:56 coding before so appreciate it 35:60 is it possible to combine a regular UI 36:02 widgets and composable functions widgets 36:04 is it a good idea yes there is ways of 36:07 combining both composable widgets and 36:09 regular platform widgets there are some 36:13 things that just aren't in compose yet I 36:16 off the top of my head I can't think of 36:18 an example but there are ways of 36:20 basically saying alright so in a 36:22 platform you I like this container holds 36:24 a composable widget and vice versa 36:27 so in this composable function this is 36:29 like a platform widget I want to add in 36:31 there so is it a good idea at this point 36:35 we're kind of forced to so if there's 36:37 something that's not available you kind 36:38 of have to use it but in the future when 36:41 everything is composed I don't think you 36:42 would want to go that route 36:47 the differences in terms of performance 36:49 between native apps UI and compose apps 36:51 UI that's actually a good question I'm 36:55 not entirely sure how compose is built 36:57 under the hood I want to say it's native 37:02 component well no they're not native 37:04 components I don't think because they're 37:05 not platform types so they're probably 37:07 doing something similar to flutter sort 37:10 of redoing it maybe I haven't noticed 37:14 any real performance difference except 37:16 for the adapter list that that's real 37:20 clunky right now but they keep making it 37:23 better 37:24 after each release so I definitely think 37:26 things will get smoother as we go 37:29 forward let's see how do you do 37:34 navigation with compose right now it is 37:37 very similar to the way you do regular 37:39 navigation you would have to like pass a 37:43 listener function down that fires off an 37:47 intent or whatever there is talk about 37:50 compose working very closely with the 37:53 navigation architecture component but 37:56 that stuff is not out yet but I think 37:58 that will make it much easier when it 38:01 does come out it'll be a lot easier 38:02 instead of kind of fiddling with 38:04 listeners and stuff like that 38:09 how does compose compared to flutters 38:11 widgets so my experience with flutter is 38:15 very very limited but from what I've 38:19 seen it seems very similar you're 38:21 declaring things in code the states like 38:25 refreshing seems kind of similar the one 38:28 major difference is composed doesn't 38:30 have hot reload 38:31 unfortunately so you do have to like 38:34 build the project and wait for the 38:35 preview to catch up or like run the app 38:38 and wait for the emulator so that is one 38:40 way flutter is a little bit better 38:45 when do you recommend to use compose for 38:47 small views whole screens I would 38:51 recommend it for like an entire screen 38:53 at least if like when it gets better 38:56 like beta at least but if you're gonna 39:00 go with compose I see no reason not to 39:03 go like all the way with it house 39:07 testing with compose yes I don't 39:10 actually know as of right now I don't 39:13 believe there are any testing tools with 39:16 compose so that is kind of a bummer I do 39:22 think that like making UI is the way I 39:25 was doing it sort of bottom-up I don't 39:28 know much about react either but it 39:29 seems very similar to like react 39:31 components so I'm assuming the way you 39:33 test react components so it'll be very 39:35 similar to the way you test compose 39:37 components and if your views are very 39:40 dumb then they should be like fairly 39:42 easy to test or kind of pointless to 39:44 test I wouldn't test my sender function 39:46 because it just displays the text 39:52 why good question when we can create a 39:55 view and XML in a few minutes why spend 39:57 an hour to achieve the same design not 39:60 considering build and push what we try 40:02 to fix my main thing is again I'm not a 40:07 big fan of the XML yes I'm very 40:09 comfortable with it I can like whip up 40:11 XML designs very quickly but not having 40:14 to do XML makes me happy inside so I'm a 40:17 fan of that also like I mentioned before 40:20 not having to dig into like the 40:24 documentation if I need something like 40:27 if I don't know an attribute I have to 40:30 go look up the documentation because I 40:31 can't really just find it in Android 40:33 studio 40:34 whereas with compose I can like click 40:36 through to the declaration for the text 40:39 or the adapter list and like find the 40:41 actual things that I need there where to 40:47 keep the reusable composable functions 40:49 in the activity that uses it or some 40:51 common class or somewhere else I would 40:54 do these very similarly to a regular 40:56 custom view so you'd have your own class 40:58 for that custom view most likely to 41:00 declaring the the main function up at 41:03 the top so for like my email view that 41:05 would be the function at the very top 41:07 all of the functions below that would 41:09 just be specific for that one particular 41:11 view so the sender text doesn't need to 41:14 really be used anywhere else except the 41:15 email view so it should be in the same 41:17 file likely private since it's not 41:20 needed definitely don't want to keep it 41:22 in the activity because activities tend 41:24 to be a little bloated as it is so just 41:27 keep them in this in their own files 41:32 hope that was not the right one so I 41:37 think what it was is with the creation 41:39 of compose will it work with 41:40 data-binding I'm not sure about data 41:46 binding I kind of doubt it just because 41:49 it kind of solves a different problem 41:51 data bindings whole thing is like you're 41:54 going from XML to a Java representation 41:58 of your view and you don't want to have 42:00 to call fine view by ID for everything 42:02 and like all all the setters compose 42:05 doesn't really work that way because 42:06 you're kind of declaring everything 42:08 anyways so 42:12 like databinding I don't think is 42:14 necessarily needed for that are you 42:18 enjoying valor ins yes I am I am not 42:23 good at it at all but it's very fun does 42:29 compose help with setting up screen a 42:30 relative layout / constraints I haven't 42:35 looked into that too much so I'm not 42:37 entirely sure compose is going to get 42:40 support for constraint layout so you can 42:43 actually build a constraint layout in 42:45 composed that's one case that I'm not a 42:48 big fan with compose right now just 42:50 because it's you basically have to build 42:53 the constraint set and manually there's 42:55 no graphical editor for it yet which is 42:57 not fun so maybe they'll add a graphical 43:01 editor for that at some point but at 43:04 this point I would kind of stay away 43:05 from constraint layout 43:12 sharing styles between composable and 43:14 yes so the styles for compose are 43:17 different than your typical platform 43:19 styles so as far as I know there's no 43:22 way of like grabbing an XML style and 43:25 applying it to a compose function 43:29 unfortunately so you kind of have to 43:32 declare the Styles manually I mean you 43:34 could create like a Master File of all 43:36 of your styles and put them in there 43:39 another thing you can do is you can 43:41 theme your application so all apps get 43:44 like the material theme at the top level 43:47 but it's it's very like restricting 43:50 right now you get like header 1 through 43:52 6 43:52 like subtitle text body text stuff like 43:55 that so it's that's one area I would 44:00 like to see compose get a little bit 44:02 better Brian let's take one more 44:05 question okay all right 44:08 have you tried split ease from Lois it's 44:12 better than Akko I have not I'll 44:15 actually have to look into that I didn't 44:16 really like unko I didn't feel like it 44:18 served like how to any benefit over XML 44:22 except the fact that it wasn't XML so 44:25 I'll have to give take a look at split 44:28 ease 44:32 alright thanks for all the Bryan's 44:34 everyone thank you so much that was a 44:36 fantastic fantastic present version='1.0' encoding='UTF-8' ? droidcon News Tech Showcases, Developer Resources & Partners /portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/home-details/EmployerBrandingHeader EmployerBrandingHeader version='1.0' encoding='UTF-8' ? https://jobs.droidcon.com/ /portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/jobs-droidcon/jobs.droidcon.com jobs.droidcon.com Latest Android Jobs http://www.kotlinweekly.net/ /portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/kotlin-weekly/Kotlin Weekly Kotlin Weekly Your weekly dose of Kotlin https://proandroiddev.com/ /portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/pad/ProAndroidDev ProAndroidDev Android Tech Blogs, Case Studies and Step-by-Step Coding /detail?content-id=/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Zalando/Zalando /portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Zalando/Zalando Zalando Meet one of Berlin's top employers /detail?content-id=/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Academy for App Success/Academy for App Success /portal/rest/jcr/repository/collaboration/Groups/spaces/droidcon_hq/Documents/public/employerbranding/Academy for App Success/Academy for App Success Academy for App Success Google Play resources tailored for the global droidcon community