How to Build a Home Screen Widget in Jetpack Compose with Glance

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys and welcome back to a new video in this video I will show you how we can build widgets for our home screen in Android using jetpack compose with the new glance API so specifically what you will build is we will be able to along click on our home screen here click on widgets and then add such a widget here by long clicking on that and then dragging this to our home screen which is a simple increment counter which you can res resize as we like and yeah that is what we'll build if we click on increment then we can increment that as often as we like so it is a stateful widget and this code will be written in compose since there is a quite new dependency we can use for that which is called glance which is still in Alpha at the moment so the functionality of this is still a little bit limited what you can do but it still looks very promising to build such widgets with a jetpick compose so let's jump into this project here this is an empty material 3 app I um I credit here and in your build at Gradle file you need to first of all add these glance dependencies so on the one hand glance and glance app widget currently it's an alpha zero five maybe be there is a newer version available when you watch this but if you encounter problems then it's probably probably makes sense to use Alpha zero five as well and what we need to do for this is we need to create a new class which represents our widget so in our root package we want to call this counter widget this widget won't take any Constructor arguments so we can safely make it on an object and it needs to inherit from galan's app widget so this is how we Define an object or class as a widget that is built with compose you see that we need to implement some functions here which is actually just one function which is this content function this content function is actually a composable which isn't Auto completed here for some reason so let's add this composable annotation and the arrow will go away and in this content function we can now write the code that defines the layout of our widget however this is not exactly the compose code we know there are some changes and limitations which you will see in a moment but in the end we just want to have a column here to display our counter text so the current count on top of our button to increment that and when creating this column we already see that there is a difference and that is that the modifier for this column is not a normal modifier of compose anymore but it is a glands modifier and all these widgets work with these limited glands modifiers so we need to not set this to modifier dot something but run the glance modifier a data background for example to set the background color to color color dark gray for example and fill Max size something like this I will put this before um so this stuff is exactly the same as before but we don't have access to all the modifiers we have with the normal compose but I assume they will add some more in future let me also want to make sure that we Center our content vertically so Center vertically and horizontally like this inside here we want to be able to on one hand display a text and here it's not important that you import the right one because there is a gland specific text and a normal compose text which you can't use here so the glance text is this one here so you can see Android X glance the text this is the one I want to import and the text is in the end just over counter we don't have the state yet so let's just set this to zero and hardcore this for now I want to change the style the appearance of our text a little bit so we can say start as a text Style font weight let's say that's medium we can set the color we need to set this to a color provider for some reason but here we can then pass our White and I'll set the font size to 26 SP import SP Alt Enter and then below this text we want to add our button and again here we need to make sure that we import the right one this is the normal compose button but we want the glance button um not sure where that is good question there's uh actually here there are two buttons um we want the previous one so this one here from Android X glance double click on that and the text on this of this button will simply be increment and what's also different to normal buttons is that on click now expects an action and not a simple callback anymore the reason is that our app isn't actually active or doesn't need to be active when the user clicks this button so we need to use some kind of special callback mechanism here which I will get you in a moment before I will comment this out though because I want to show you how we can now have state in this because that also works a little bit different so in here we want to get access to our actual count which is a state in the end and that can be retrieved with current state and you can see we need to pass a preferences key so the way this glance API works is that under the hood works together with datastore so our preference storage and every time we change the state it's updated in the preferences to and then reflect on the widget and for this key we need to add this here to our counter widget so that is our account key and that is an INT uh int preferences key which we simply call count and that is just the the type of class that datastore works with we can then pass it here count key and if that doesn't exist we just set it to zero and by default we can then say here for text that we simply show this count.2 string and now let's get to this button to implement this on click action and for that we actually need to create a separate class which we can do below here can be an object again called increment action callback and that is a type action callback and in here we need to implement um on action this function is called when we click on the button then that gives it access to the context the glands ID so which widget that is and some parameters we could optionally pass here so if we need some data inside of this on action block which will then be triggered and in here what we can do is we can say we want to update the app widget state um so we in the end just want to update our account state passing in our context and our glance ID and then opening a Lambda block here we get access to mutable preferences so in the end there is nothing else than our data store instance where we can now update the value of our account so it will reflect on the widget so the current count is prefs at the with the key of counterwidget dot count key and if that current count is not null so if it exists if we already saved something we just want to take our prefs with a counterwidget.countkey and we'll just set this to current count plus one so we just increment that else however if that doesn't exist yet so when the first try to update this we set this simply two one so the first increment will just set this to one and then the value exists so on the next time we just increment it by one and after we updated the state we also need to tell the widget that we did that and we do this by saying counter widget that update passing in the context and the glance ID and then this will also reflect on the widget then we can scroll up and use this callback in our button which I will uncomment again oops not that I mean this this this and on click will now be an action action run callback you can see there are more types of actions you could use here you could also send a broadcast to a broadcast receiver you could start an activity when the user clicks this we just want to execute something here in callback so action run callback which will be in increment action callback in this case double colon class.java to receive this we still need a special kind of broadcast receiver which you can create here so class I call this simple counter widget receiver which is a glance app widget receiver and all we need to do here is we need to overwrite the um glance app widget variable which is simply the widget we want to show so our counter widget so far so good we now Define how our widget looks like and what it is able to do but we still need to Define some metadata so we actually find this in our widget tab when we long click on the home screen and we do that with an XML file in our Ras folder Ras XML right click XML resource file and I'll call this counter widget info and the word element won't be a preference screen but rather an app widget provider clicking ok and in here we can remove this piece of code and Define everything in here so here we just Define the basic information like the description for example so what will display for that specific widget there needs to be a string resource um I'll just use the app name here just as a demo we can define a Min with for example for this which I will use 50dp4 I will say um Min height actually 50 DP we can define something like the resize mode so if we can only recess this horizontally only vertically um or both or even not at all so let's say you want to be able to resize it as we want so we say horizontal and vertical I want to say that the widget category is for our home screen there are some more details you could configure here for example Max resize width so how much you could resize this in width and height you could provide an initial layout which is provided by the composable already but this preview layout is something good you would need to provide with an XML layout and that is the preview you just saw here when we long click demo um so if we long click widgets this thing here so if you want this to look like something like for this clock for example you would need to provide an XML layout for this sadly but as soon as you drag this on your home screen it will actually look like this okay um that's actually the minimum information we need here last but not least we need to go to our manifest and kind of register this widget So Below this activity I want to register Our receiver we specified the simple counter widget receiver we also want to set export it to true so that any app can send these broadcasts here and then specify an intent filter when we pass the action name and paste this piece of code so this is the type of action you want to receive this will be called from the glance API in the end and sent to our broadcast receiver when the widget needs to be updated and for the metadata we can Define this here or actually instead of one block on the one hand the name is our XML oh no that is the resource for the name we want to refer to Android that app widget dot provider and the information for this is provided by the resource XML what do they call it um here we need to probably paste this here at XML slash counter widget info like this and if we Now launch this this should be everything hopefully it compiles and builds and then we should be able to see our app here this of course comes from our old app I'll remove the widget very quickly and I'll get a duplicate class issue I know why that is happening um you might not get that but that is cost because I have the wrong composed version I need to update this compiler to 1.4.2 and this one here as well and also the kotlin version 2 8 1 0. I had that multiple times but this I forgot to update that before so let's quickly sync rebuild and launch there we go here's our empty app of course nothing the app is doing right now because we only build a widget but if we now long click go to widgets and then we see widget would compose this is our new app if we open this we can long Click put it on our home screen and there we go looks exactly like before we can resize it as we want and if we click this button and then oh we get an issue here um what is it um the increment callback is not accessible from our run code like that's interesting so it doesn't work at all okay also if we resize it then no okay I will need to look into that and get back when I fix it okay apparently glance wants this increment action callback to be a class since it tries to create an instance of this which doesn't work with an object so let's replace this relaunch the app take a look here and if we now click increment yes now that is actually working very cool so we have a working widget so I hope you enjoyed this video if so you will definitely also enjoy my more advanced Android premium courses which you can find all down below I of course about cicd a multi-module websockets testing kmm all these advanced stuff that you need in the Android industry nowadays so that's not good to you click the first link and check these out and apart from that I wish you an amazing rest of the week and see you back in the next video bye bye thank you
Info
Channel: Philipp Lackner
Views: 18,695
Rating: undefined out of 5
Keywords:
Id: bhrN7yFG0D4
Channel Id: undefined
Length: 14min 28sec (868 seconds)
Published: Sun May 21 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.