ViewModels & Configuration Changes - Android Basics 2023

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys and welcome back to a new video in the next part of Android basics in which I will talk about so-called review models and view models themselves aren't a concept that only applies to Android apps but they have some kind of a special place on Android and in this video I will explain why [Music] I will start with some Theory here so you actually understand what a view model is and then I will show you some examples in code so normally when we build apps then we try to bring some kind of consistency into our code base so that it remains scalable and understandable and for that we typically use so-called architectural design patterns so maybe you've already heard of mvvm mvi MVC MVP there are a lot of different such design patterns out there which outline kind of rules how we should structure our application and on Android specifically mvvm is one of the most popular of such design patterns and at this point we really don't need to understand that pattern itself in detail it's just that mvvm stands for model view view model and you can see there is this view model involved in that design pattern and if we just take a look at this rough design pattern here at this sketch then the view as you can see on the left but that is basically just your app's UI so you want to isolate the UI so just what's visible on the screen for the user then on the other hand we have the model which is where your app's data lives so for example if you have a contact list app then this would be the place where you have your database and where you save your list of contacts but also for example if you interact with the remote API then this will also live in the model and the view model is now the bridge between the view and the model that is why it's called viewmodel you can see it's in between here and its job is now to on the one hand take the raw data from the model so for example your list of contacts in your contacts list app and then it will take that data and bring it into a new format which is easy to display on the UI because very often we save our data in a format that we don't want to use exactly like that on the UI an example would be that you have some kind of Unix timestamp that represents a specific date and time which in the end just a long number so it's it's really easy to save that in a database but if you would show that Unix timestamp 2E user then that wouldn't be understandable the user would not be able to guess what date that is in their local time zone they would not be able to guess what time that is so what the view model will now do is it will take that contact from the model with that Unix timestamp and it will convert that to a format the UI understand so in this case it will probably just format the date to a real readable date and then as soon as that happens The View model will then automatically notify the UI that there is a change that there is a new contact in the context list so the UI can update and show that new contact on the screen but it also receives such events and actions from the other side so from The View since when there is some kind of UI action as you can see here and that can be something like a button click or maybe the user swipe to a different page on their screen then this is considered a user action and the view so the UI will then send that user action to the view model so the view model can react to it and this can either be that the viewmodel just changes some state for example you click on a button and suddenly the background color of your app changes to red or so that would not need the model in this case since the UI action would just be the boom click the view model update the state that the background color change and notifies DUI so the UI can show the new background color but what could also be is that the user clicks on some kind of button save new contact for example when they entered all details the name phone number for new contact they sent that data to the view model and now the v-model needs to take it and also send it further to the model since that contact needs to be persistently saved so in that case whenever something has to do with a real data source then the model gets involved on the viewmodel sends that new data to the model the model saves it notifies the viewmodel again and the view model will then notify the UI again and normally these view models are pretty much just models for a view so that can be just one single UI component such as a list item however on Android it's much more common that we actually have one view model per screen so that this view model would just accept all user actions that come from that screen and then also keep all the states so all the values that can change over time that have some kind of effect on how the app looks like on how the UI looks like and would then also send these updates again to the UI so the UI can also show these properly and I want to show you such a view model in action how we can create an Android and then after that we'll explain why they really have that special place on Android and also why I decided to make that a separate video in the Android Basics playlist even though the viewmodel itself is not an Android concept but rather just the concept of these design patterns that use view models so I'm here in a very blank Android Studio project and all I really want to do for viewmodel is we want to create class A View model is nothing else than just a plain class so now a root package let's create a new file sample view model for example or we could call it contacts viewmodel if that would be for a contact screen we make that a class and boom we have a view model that's really everything about it for now and in here we would now put in all the functions that the UI would call when there's some kind of user action again for example a button click for example to change our background color um to take the simple example from previously so if function change background sound color and this could of course also take some parameters but in this case you want to keep it simple and just change it from white to Red for example so we now need some kind of variable that will trigger the state change so the change in the background color which will then notify the UI there is a new background color please show that on the screen and now you have to be a bit familiar with the jetpack compose which is what we use for building UI on Android if not I will still try to keep this as simple as possible but for um yeah Deep dive into jetpack compose I have a crash course a one hour crash course and a more dedicated playlist towards this topic in the end we want to have actually a public VAR called background color for example and here we can say that is by mutable State off so we make that a jetpack compose State and whenever this variable node changes on jpeg compose is built in a way that it will receive these updates automatically so it can react to this new background color it is a mutable State off now we need to set in a default color which is just white for example Alt Enter to import this Alt Enter import this again and then what we also usually do is we make that a private set so we only want to be able to change these states like so these values that can change over time such as this background color in this case from within this view model we don't want that the UI calls something like viewmodel that background color is equal to Green because the responsibility for this to change the state and to notify the UI is solely here in this view model and with this private set we just make sure that the UI can read this property but it cannot set it and now when the user clicks on the button to change the background color we will call the model that change background color and in here we now just want to change this background color for example to color dot red so this will just update the property and since this is a compose state it will notify the UI which can then update so yeah the UI correspondingly so now we can go to main activity and in here in set content that is where we put our UI set up again if you're in compose or new to Android UI building then don't put too much Focus here on this you don't need to understand that in detail what happens here but just to be able to show you a click on a button we need to build a little bit of UI here um so on the one hand let's actually leave the surface um where we can assign a background color let's remove this comment but inside of the service we want to have a button and here we have an on click Lambda which gets called when we click this button instead of this block we can just put some text that will be displayed on the button something like change color and when we now click this button we now want to have a view model instance of which we then call this change background color function and we can just create this remodel instance here and that is now very basic this is not the final form I will explain some issues of the approach I will use now but just that you really understand the whole concept let's do it step by step so let's say we have a private Val view model and that is just a new context view model and by the way if you were to use a model so some kind of data source maybe in form of a repository then you would just put this in the Constructor of the context view model you could use it in here so the data source the repository and um yeah then the viewmodel would communicate with that and every now go to our button and say viewmodel dot change background color and we go ahead to this surface color here and we change this to viewmodel dot background color so it will always take the color from overview model and then launch our app on our emulator and wait a little more moment until that is booted up and okay for some reason the button fills the whole size which I think is because of the service but it doesn't matter we should see the background color change here where we still have these wide sections on our screen right now it's white but if we click this button then you can see it turns red but now let's finally come to why view models have this special place on Android let's take a look what happens if we rotate our device as you can see Boom the background is white again if we now click change color again it will turn red but every time we rotate it it will just reset and this is also not only the case for screen rotations but also for example if we switch our theme by going to our settings here and triggering dark theme let's change this to on and you will see we suddenly have a wide background again it's not red so what the heck happens here and I already teased this a little bit in the video about activities and their life cycle because what happens here inside the activity when we rotate the device then that is called a configuration change and on Android we have lots of these configuration changes our screen rotations are the most common one but it basically just means a change in configuration configuration can be that the user changed the language and the app just needs to update all strings in the app it can be changing the theme so the app needs to update all colors of all views in the app but it can also be something like a screen rotation where the app just needs to show a potentially different layout which is used for landscape mode and the way Android handles these problems when such configuration changes is it will completely recreate the current activity recreating means the current instance of the activity is completely destroyed the lifecycle will move till the undestroyed state all resources are freed up and then when the return to each and finished it will start with a completely fresh new activity and what will happen in that case is when the screen rotation finished the main activity main activity will be completely recreated and that means the view model innocence here will also be recreated so all the values in the view model will be set to their default values again and this is of course something we don't want because that is something a user would never expect that when they rotate their device the screen gets completely reset and all the states get reset with their default values and that is why Google introduced their own kind of version of The View model which Stills has the same responsibility as a normal view model in the nvvm pattern so if you were to build an IOS app with the mvvm pattern then it would work just like this because iOS doesn't have this problem of configuration changes but on Android what we need to do is we need to go ahead here and we need to make this context view model inherit from viewmodel which comes from Android X lifecycle so then it is officially an Android view model you can you can call it so and what this will now do is it will create a component a view model which will outlive the life cycle of its screen in our case the screen is the activity and the activity has a certain lifecycle which ends when we rotate the device then this view model since it now inherits from viewmodel will outlive that so that means the view model won't get destroyed when the activity gets destroyed Instead The View model will only be destroyed when the user actually actively pops the activity from the back stack so when the user is on the activity and clicks on the back button so that means they want to go to the previous screen so yeah that screen is not needed anymore with this view model and then the view model will be destroyed but it won't be destroyed for simple configuration changes and right now if you take a look in minactivity this will still not work because we still again initialize a completely new view model instance whenever this activity is created instead we also need to use the Android way of initializing a view model for which we have mainly two options on the one hand we can say buy view models this one here and then we specify the type of review model so contacts view model and if we now relaunch this take a look here if we then click the button it will turn red if we now rotate the device you can see the the background will now stay red because we really created that Android specific view model instance which will outlive the lifecycle of our activity but very often you're also deep down in some compose screens and you don't have direct access to the activity to initialize your view model in that case what you can also do is you can remove this and you can use a specific compose import or compose version to initialize that so you could say well view model is equal to view model it actually needs a specific dependency so to be able to have this version of initializing a viewmodel in compose you would need to go to Gradle scripts build that Creator module app and in here um don't worry you don't need to understand that for now if you're new to Android you need to scroll down to this dependencies block so here you can basically just include third-party libraries um also first public libraries if it's one from Google like this one and you would need to paste this line implementation Android X lifecycle lifecycle of your model compose and then we're going to synchronize this so click sync now and go back to main activity when that sync is finished we should be able to see this new function if we type is equal to viewmodel yes this green one here also just use this we can just specify that this is a context view model and then again if we launch this we should see that this still works if we have a configuration change okay I get some duplicate class issues here if you don't get that then ignore it that's fine but in my case this sometimes happens when I create new project and we can simply fix this by updating the kotlin version for that we go to build.gradle Project we change the carton version to 1.8.10 and in our build.gradle app file we change this carton compiler extension version to 1.4.3 synchronize this and this would this should hopefully fix it yes that is looking good so my app is launching if I click change color now rotate the device and then you can see the background will remain red just one more thing you will notice as soon as you use a Constructor for your view model right here for example to provide some dependencies the viewmodel needs so some other classes like the model for example in form of a repository class but let's just keep this simple and pass a simple hello world string or so then you will notice that if we launch this take a look here our app will crash why is that because now Android suddenly doesn't know anymore how it should create that view model instance since it needs some Constructor parameters which we did not provide and since we have to use this special way of initializing viewmodel with this and we can't just create it with like yeah just like creating a normal class where we can pass the Constructor arguments Android doesn't know at this point how to do that and what we need in this case is a so-called viewmodel Factory so basically a class that defines how our viewmodel instance is to be created later on there are solutions on Android and dependencies and Frameworks you can use to kind of bypass this or to delegate this to some kind of code generator so you don't need to write this Factory on your own but by default this is still needed for every single view model that needs some form of constructive arguments and we can do this by going into inside of these parentheses hitting Ctrl or command p and you can see there is a parameter called Factory which needs to viewmodel provider.factory and we can assign that here by saying Factory is equal to this piece of code but actually not a Lambda function we can just return a new instance of a view model provider not Factory you can of course also put this Factory in a separate file or instead of the viewmodel file and then just create an instance of it here and here we can override the create function um we just want to override the normal create function with just the model class parameter and this is called when Android tries to create an instance of your viewmodel and by default it's just called super.create which will just try to create an instance of your viewmodel if it does not need any parameters it will work and else it will crash as we just saw we on the other hand now want to remove this and replace it with context view model so we can now return an instance of this and here we can now provide our hello world string like this and we also need to cast that as a generic type T so that Android Studio doesn't complain here if we Now launch this on our device then now we should not see a crash because our app is working it knows how to create this view model if we click this button then the background will change to red again so those are really the absolute Basics about view models in Android there are some further Concepts um like the lifecycle of a v-model and how we can scope viewer models and their lifetime to specific parts of our app since we don't always want to scope them through the whole activity which would basically mean we have one view model for our whole app if we use a single activity or at least all of your models would live as long as our app lives but we usually only need them for a specific screen but there are also ways to for example share one viewmodel instance across multiple streams which I have a separate video about um but I think this video should have already covered the most important aspects to help you understand what view models are how you can use them in your code and why they have such a special place on Android and why you will see them in most products out there so if you like this Android Basics video then you will definitely also love the future Android Basics video which will come very soon so definitely subscribe to this channel to not miss them thanks so much for watching I will see you back in the next video have an amazing rest of your week bye bye foreign
Info
Channel: Philipp Lackner
Views: 12,522
Rating: undefined out of 5
Keywords:
Id: 9sqvBydNJSg
Channel Id: undefined
Length: 18min 45sec (1125 seconds)
Published: Sun Jun 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.