in this video I'm going to start the
process of converting our calculator app
to use a view model the calculator app
that we've created earlier in the course
is a very simple one so it'll be very
easy to see how the view model
fits into the overall architecture we'll
see how to create and use a view model
but more importantly what that view
model can do for us and I just want to
make it clear that this is a very simple
example and you almost certainly
wouldn't use a view model in this app in
practice so they'll be clear I'm not
suggesting that you use view models all
the time we're converting this app to
demonstrate how a view model separates
the logic from the user interface UI so
our main activities going to do nothing
more than display the UI to the user and
respond to events like buttons being
tapped it responded to those events by
calling functions in the view model and
it's actually up to the view model as to
what happens when those buttons are
tapped the activity will observe the
view model using live data so that it
can reflect any changes in the UI that's
all that's going to do display data call
view model functions when UI events
occur in update itself when data changes
everything else will be handled by the
view model in more complex apps there
might perhaps be a business logic layer
and a data base but we're taking baby
steps and starting slowly here at the
moment alright so as you can see on
screen I've got the calculator app
opened and this is the calculator app
from earlier in the course we're going
to start converting that to use view
model you can download the project from
the resources for the last video in the
calculator section if you don't have it
available locally on your computer now
if you get problems opening the projects
from the resources try the files in
validate cases restart option other
words up here if you happen to get an
error file builder that caches restart
and go ahead and click on invalidate and
restart and you may also need to rebuild
the project but in my case I've got it
working okay and as it turns out before
we start there are a few suggestions
from Android studio in main activity if
I score I don't have a look here you can
see here we've got a suggestion there
for Android studio regarding a lambda
right him
it actually says where lambda arguments
should be moved out of parentheses and
to do that I can just come over here
click on the light bulb and there's an
option there to move at land or argument
out of parentheses I'm going to click on
that that removes that first warning
these lint checks are revolving all the
time so don't be surprised when you come
back to a project and find suggestions
and warnings that weren't there before
this was the case here now that we've
changed that first one there's a
suggestion also over here if I move out
of view that the parameter view is never
used and could be renamed or if we have
a look at that warning again could be
renamed to and underscore doing that
tells the compiler that the parameter
isn't used and also allows it to
optimize the code sometimes but if we
come over there and click on the light
bulb there's an option over there for
another option remove single lambda
parameter declaration so I'm going to
click on that to accept that suggestion
as well alright so that's no turn it up
we've no longer get anyone so you've got
a green tick now in the top right-hand
corner of that class so we now need to
create a new Kotlin file class let's do
that so I'm going to right click on the
calculator package new Kotlin file class
and we're going to call this one
calculator view model okay there's a
view model and the class declaration
line will be class calculator view model
and we need to extend the view model
class to create the view model for this
app so it's : view model and then
parentheses then left or right curly
braces if you were prompted make sure
you import the class from Android arch
that life cycle don't view model but you
can see in line three the imports happen
for me automatically all right so now
that we've done that the next step is to
move everything out of the main activity
class that's not related to the UI so
any processing and all state will be
moved to the view model what I say all
state I mean all state that's not
related to the UI the activity will
still take care of restoring the
contents of edit text widgets following
following a rotation for example
but that's handled by Android anyway
along the way as we do this we're going
to get a lot of errors but that's good
because it highlights the bits of code
that we would be looking at now all that
we should be looking at rather so
opening up our main activity you can see
right at the top here we've got a couple
of variables destroying the operand and
the pending operation now they're
functional not UI variables so I'm going
to cut them out of here
along with the comment that we added to
that effect and we're gonna paste them
at the top of the calculator view model
class okay back to our calculator your
model and I'm going to paste it directly
in the class there for our calculator
view model and obviously now that I've
done that as expected
we've got a load of errors now we're
going to go through this process of
fixing those so looking now at the
various functions that are in this class
an obvious function that's got nothing
to do with their UI is this perform
operation function if you recall that
takes care of the calculating and we can
freely move that into the view model so
I'm going to cut this function entirely
out of main activity and then we'll
paste it into the calculator view model
there cutting that out calculate a view
model I'm going to paste that in now
that when you do that you get this
option about accepting or is it okay to
accept the synthetic imports we don't
want to do that so I'm gonna click on
cancel here instead just make a bit of
space so this is battaglia remember that
the view model mustn't hold any
reference to the activity referring to
the activities widget is a definite
no-no which is the reason we've
cancelled that if you did happen to
accept the imports by mistake don't
worry we can't delete them later once we
change the code or you can just do an
undo and repeat the operation but for
now you saw that I didn't accept those
synthetic imports so go back to main
activity again you can see that there's
no errors in the unsaved instance state
and on restore instance state functions
we're not interested in saving State now
that's the job of the view model so I'm
going to delete these two functions
entirely
and once we do that we go back up to the
top of the file we've got these three
constants here now then longer being
used is there the bundle keys so for
that reason we can now delete those
entirely now we're really breaking
things at this point because we never
got errors in both classes both
mainactivity and calculator view model
showing errors but that's actually quite
normal when you perform a significant
refactor to an application like we're
doing right now let's move over now and
focus on the calculator view model class
now in our perform operation function
the last two lines are referring to
widgets in the activity now that's for
bidness we know to access widgets
directly so we need to change those
lines to use local variables instead and
I'll do that in a moment now these are
the this is the code with errors on
lines of 37 and 38 when we come to
change a widget reference to a variable
it's obvious then that the widget isn't
going to be updated these two lines
update the result in the display if we
don't update the widget then obviously
we need some other way of showing the
result back in the UI this is where the
Android live data class comes in we saw
that mentioned in the documentation in
the previous video and if you could I
have a few which I'm just gonna bring up
in the browser now you can see here that
says live data is an observable data
holder class so that means that our
activity can observe it and react when
it changes live data is also life cycle
aware it won't attempt to notify an
observer about changes unless the
observer is active so how to read
through this document and also follow
the various links once we've got this
calculator app working because it
describes how activities are
automatically and subscribed when they
get destroyed for example we don't have
to concern ourselves with unsubscribing
manually and we'll also get
automatically subscribed again if the
activity is recreated as a result of a
configuration change now if we scroll
down a little bit down here you'll be
able to see that there's a section here
called working with live data objects
this will make more sense when you've
seen them used in our app so I do
suggest you come back to this later and
most of what we're going to do is
covered here
the section down here create live data
objects show some sample code to create
a live data object this is still Java
code but Google are updating all their
examples there is something wrong with
that example though we'll see what that
is when we've checked out the next
section I want to look at so scrolling a
little bit further we're going to get to
the update live data object section this
one here update live data objects this
talks about or which reduces another
class this is the mutable live data
class in fact scrolling up a bit if we
come up and look at our code example
there you can see here that in current
name is to clear this immutable live
data type so a live data object doesn't
have any functions for updating it you
have to use a mutable live data for that
and that's actually what's wrong with
this example code here the mutable live
data object in current name is public or
more specifically the get current name
get a method that exposes it is public
and returns a mutable live data object
so that means there's nothing to prevent
the UI from updating it this snippet
shows basic usage not necessarily best
practice the activity could call the set
value function to change M current name
it shouldn't the whole point of this
exercise is to separate the UI from the
apps logic but there's nothing at the
moment to prevent it with this example
code so when you go to the trouble of
finding these documents read them
carefully even if some of it doesn't
make sense it'll be there in the back of
your mind you'll be surprised how often
something that doesn't make sense
suddenly does when it's time to need it
and actually use it alright so I
apologize for all the scrolling but I'll
just scroll back down now to the update
live data object section here it's
talking about the set value and post
value methods of the mutable live data
object he used these to modify their
values will be using set value but if
the code that's changing them is running
on a separate thread in an async task
for example then you'd use post value
instead of course we're using Kotlin not
Java so we'll refer
to the value and post value attributes
instead of calling this setters the
final sentence of that or in that first
paragraph is why I suggest reading the
entire document even if you think you've
found what you need further up it
actually says there that up here usually
mutable live data was used in the view
model and then the view model only
exposes immutable law of data objects to
the observers so we're going to start
off exposing the mutable live data
objects and then we'll change the code
to only expose live data which the
activity can't change alright so back to
our code so at the moment we've got two
references to two widgets so we need to
replace those with live data objects so
let's actually declare the two objects
first so below the private fire pending
operation line move into eval result is
equal to it's going to be mutable live
data of top string and let the
parenthesis on the end I'm going to do
this same for new numbers had Val new
number equals it's going to also be a
mutable live data or type string there
and we can have the parentheses again so
now that we've done that we can replace
these two widget references down here on
line 41 and 42 with our mutable live
data objects so I've used the same names
so the change is trivial instead of
setting the text all we need to do is
set the value instead of result dot set
text we're going to change that to
result dot value equals and get rid of
the parentheses and operand 1 dot 2
string and on the next line it's going
to be a new number and set up text it's
going to be value equals and I'll remove
the parentheses and leave the double
quotes in there now if you had some
synthetic imports at the top of the file
in the input section they should now
have been removed if not though you
could safely delete them we're using
these variables now not references to
the activities widgets as you can see I
haven't got any of those synthetic
imports showing anymore
all right so let's end the video here in
the next video we've still got some work
to do because we've still got some
errors showing in main activity so let's
work on cleaning the main activity class
up in the next video