Hi everyone! This is Belal Khan and you are watching Simplified
Coding.So we created the user interfaces for our login and signup screen now let's move
ahead. So we are trying to implement MVVM that is
Model View ViewModel architecture pattern and it says at the top we have the views or
the UI that we design which is activity login and activity signup. Right now our task is to implement the user
login functionality. But remember we cannot do everything inside
this login activity because we need to follow the architecture pattern, and we need to separate
the concerns that is this activity should contains the logics that are only responsible
for handling the UI elements. So now first think about what are the tasks
that are involved when a user logs in. So when a user logs in or a user wants to
login, user opens the app user enters the email and password in the app then we get
the email and password from the UI and we send the email and password to our RESTful
API or web services to authenticate the user and then from the server we get the response
back that whether the user is authenticated or not so this is what happens when a user
logs in so this part when the user enters the email and the password is directly related
with our UI and we can code this thing in our login activity but this part where we
send the email and the password to our web server that means we need
to perform a network call we cannot put this thing into our activity and this part we need
to separate out from our activity and as our architecture pattern says at the top we have
the activity or the UI and the UI is directly dependent on view model so what we will do,
we will send the email and a password to view model then view model will send those things
to repository and then repository will perform the authentication so this is how we need
to do it. Maybe it is confusing to you but that is how
it should be done. And it is actually very easy so when we will
write the actual code you will understand everything so let's do it. So this is our login activity and inside this
activity we can get the input of email and password but for getting the input we will
not use that traditional way that was get text from the edit text. So we will not do it like this instead we
will use the two-way data-binding to get the input automatically and when you want to do
this you need to create a view model for your activity or fragment in this case we have
activity but creating the view model part is always the same you just need to create
a class and I will create a class inside this auth package so right-click go to new
select Kotlin file class and I will name it AuthViewModel and this is a class. Now I will use the same AuthViewModel for
login and sign up activity because the functionalities are pretty much the same. When you want to create a ViewModel you need
to extend ViewModel to your class so I will extend ViewModel in this class ViewModel now
inside view model I need to get the email and the password from the UI and to do this
I will define two string variables so define var email of type string and the initial value
is null and that is why we have a null safety operator here then
the same way we will define password of type string and the initial value is null. Now these variables will be used for getting
the email and password from the UI but we have a button as well and that button when
clicked we need to perform the login and for this operation we need to define a function
here so I will define fun onLoginButtonClick or you can name your function anything but
because this is a click function you need to pass view as a parameter here. This is very important now inside this function
we will check if email isNullOrEmpty or password isNullOrEmpty. So if this is the case what we will do we
will display an error message but how we are not inside an activity so I will tell you
how you do this but after displaying the error message we will
stop the further execution and for now just for this video if the control comes outside
this 'if' we will consider it as a success or authenticated so let's write success here. So we have the function which is our on click
function and we have two variables to get the email and the password now if I want to
use this AuthViewModel to my activity_login.xml then what I need to do is I need to convert
this layout as a data binding layout and if I want to do this I need to cut everything
so I will click here to collapse this tag and I will
cut everything ctrl+X, now I will create a layout like this so first we need a layout
tag if we want to use data binding then inside the layout tag I will paste the thing that
I just cut so paste it here and now expand it. Now I will cut all the namespaces from here
and I will paste it inside the layout tag, that's it. Now this layout tag has two elements first
one as data where we define all the data that we use to bind in our layout and the next
one is our actual layout that starts from coordinator layout and I will also give
an ID to our coordinator layout so let's give it an ID and I will give it the ID like root_layout
that's it. Now you might see this problem as well and
the problem is the layout is not getting rendered and I guess it is a bug with the new material
design so if you are facing something like this go to design and change your app theme
to AppCompat.Light.NoActionBar and it will work. You see it is working so I don't know maybe
it is a bug but it is fine now. Now inside the data we will define our ViewModel
and to define our ViewModel we use the variable tag and for the variable
tag we need to define two properties the first one is the name of our variable and you can
type any name so I will type viewmodel and for the type you need to write the full path
of your ViewModel class so in my case it starts from net.simplifiedcoding.mvvmsampleapp so
I will write here net.simplifiedcoding.mvvmsampleapp.ui.auth and then my AuthViewModel so you need to write
the complete path here, it is very important remember this thing. Now we have the view model in our layout and
now we can use this ViewModel to send the input values to these variables which are
email and password so let's see how we do this to do this come inside the EditText and
inside the EditText we will define one more property and this property is
android:text now for the text we will write @= and then we will put curly braces and here
we will write viewmodel.email, now this means whatever value we will enter on this
EditText it will be assigned automatically to our viewmodel.email, which is this email
var. Pretty simple right and the same way we will
do for password we just need to change this email to password and now we will come inside
the button so this is the button and here we will define android:onClick @ then curly
braces, inside the curly braces viewmodel then :: and then the name of our function
so I will do some copy paste to make sure I don't write or I do not make the mistake
of misspelling because if you write a different name there it will not work. So we need to write it exactly like this so
ctrl-c and ctrl-v. Now whenever I will click on this button this function as called but
how we get a callback from this view model to our activity to display the error or success
message and to do this we need to create an interface so inside the auth package, I will
create a new file which is Kotlin file and this time I will create an interface
and I will name this interface as auth listener inside this interface I will define three
functions the first function as fun onStarted() because the login is a network operation and
it will take time so when the operation is started we need to display progressbar to
the user and that is why we need this function to know when the operation has started to
display the progress bar. So we have fun onStarted() then we have fun
onSuccess() now this function we will call when the authentication is successful and
we have one more function onFailure() in case of any failure and when the operation fails
we need to get the reason why it failed, so to display the reason I will define a message
of type string to this function now I will implement this AuthListener to our LoginActivity,
so I will implement AuthListener here. Now because I implemented the interface in
our LoginActivity I need to override all these functions and to do this just press alt +
enter and then select implement members and select all the three functions
and I will remove all the tools and I will cut everything and I will put it after the
onCreate() function because this is the way I like. So everything is fine now. For now I will just display "on started",
"on success" and "on failure" as a toast and writing toast
every time like toast then make text and then show it as a headache okay so that is why
I will create an extension function to display toast and to store these kind of functions
I will create a separate package inside my main package. So I will create a package named util
inside this package I will create a file and I will name it view utils and inside this
file I will create an extension function for context so I will write fun Context.toast
toast is the name of the function and to the toast I will pass the message that I want
to display as the toast that's it. Now here I will make a toast so Toast.makeText()
then this, we can pass this for the context because this is an extension of context then
the message and then the length of the toast and then finally show(). Now I can simply call toast to display our
toast so come back to login activity and here I will write toast("login started"). Again toast("login success")
toast and in case of failure I will display this message so let's display that message
and everything is fine now I need to get this listener into my AuthViewModel so that is
why I will define one more var here and this time it is a var authListener of type AuthListener
and again it is nullable and the initial value is null now when we will click on the login
button we will call onStarted() that means the login task has started in case the
email or password is empty we will call onFailure() and we will pass the string
like invalid email or password in case it is a success we will call authListener?.onSuccess(),
that's it now we need to add this listener and we can do this inside LoginActivity but
first we need to get the ViewModel and we also need to bind the ViewModel to our activity_login
and if you want to do this you need to remove this setContentView() and you need to get
a binding instance that is generated automatically so to do this you need to write val then your
val name you can write any name so I will name it binding equals
to we will use DataBindingUtil.setContentView() this time it will take the first parameter
as the current activity and because we are inside an activity we can pass this then for
the second parameter it takes the ID of our layout so we can pass R.layout.activity_login
that's it. Now it will return us an instance of ActivityLoginBinding. You can see, it is here, But this class is
automatically generated and the naming convention is according to the file name of your xml
file so in my case the name of my xml file is activity_login
so that is why it generated ActivityLoginBinding so this is the naming convention. Now we have the binding, after binding we
need to get the ViewModel and to get the ViewModel you need to create one more val, val viewmodel
and you will get it from ViewModelProviders and you have two classes one is ViewModelProviders
and one is ViewModelProvider, make sure you use this first class with an s. So we will use ViewModelProviders and then
of. Now this of function takes the current activity
as the parameter and as we are inside an activity we can pass this and then we will call the
get() function to get the view model and inside this get we need to define our ViewModel class. So here we will write AuthViewModel::class.java
that's it. We have the ViewModel, now we will set this
viewmodel as our binding viewmodel so we will write binding.viewModel = viewModel now it
will bind our data with the UI but in this case we are just getting the data from the
UI now we also need to define the AuthListener to our view model and to do this we just write
viewModel.authListener which is this authListener and we will assign it to this because this
current class contains our AuthListener. And everything is fine now if you will run
your application, let's run it now. Let's try clicking on the Sign In button you
can see we are getting the message invalid email or password so what is happening here,
this function is getting called so we are getting onStarted() the callback that we have
inside our login activity then the email and password was empty so again it is calling
on failure and we are getting a message invalid email or password if you put a correct email
or something inside email and password EditText because we are just checking if it is empty
or not so if this is the case it will call onSuccess() you can see login success so it
called this function and from here we are displaying the "login success" toast
so this is how it is working. You see it is pretty easy we separated out
the logic from the UI so now inside our AuthViewModel we have the email and the password now the
AuthViewModel will interact with our repository to perform the actual login operation. But we will do this thing in the next video
so that is all for this video friends I hope you are getting it; in case you have any question
let me know in the comments and if you think my efforts of creating these courses worth
something then please like this video and tell your friends to subscribe to my channel. Thanks for watching everyone
this is Belal Khan, now Signing Off.