In our case, The ViewModel can send data to the layout and also observe changes.
For this, we need a BindingAdapter and custom attribute defined in the XML.
let's see a very basic example of a login page using the MVVM pattern...
Project structure:
Enable data-binding:
have to enable data-binding in Gradle file:
note: do it in the app-level build file.
android{
dataBinding{
enabled = true;
}
}
Adding dependencies:
implementation 'android.arch.lifecycle:extensions:1.1.0'
Model class:
The model would hold the user details, like user name and password, here User is model class ,
package com.javaoneworld.mvvmsample.model;
public class User {
private String email;
private String password;
public User(String email, String password) {
this.email = email;
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Data Binding allow us to bind the data in XML layout, so there is no need of findViewById in our acticity class.
Syntax- @={variable}
So there is one more very important thing in data binding case,
We have to wrap up our layout in <layout>.........</layout> tag,
means that our root tag must be <layout>.
and <layout> contains two thing...
Data
Layout(UI or View)
Data contains two thing,
- name
- type
Layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.javaoneworld.mvvmsample.view_model.LoginViewModel" />
</data>
<RelativeLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/inEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:text="@={viewModel.UserEmail}" />
<EditText
android:id="@+id/inPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="password"
android:inputType="textPassword"
android:text="@={viewModel.userPassword}"/>
<Button
android:text="Login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:onClick="@{()-> viewModel.onLoginClicked()}"
bind:toastMessage="@{viewModel.toastMessage}"/>
</LinearLayout>
</RelativeLayout>
</layout>
And finally here is ViewModel
ViewModel:
package com.javaoneworld.mvvmsample.view_model;
import android.text.TextUtils;
import android.util.Patterns;
import com.javaoneworld.mvvmsample.model.User;
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import androidx.databinding.library.baseAdapters.BR;
public class LoginViewModel extends BaseObservable {
private User user;
private String successMessage = "Login was successful";
private String failedMessage = "Login failed";
@Bindable private String toastMessage = null;
@Bindable private String userEmail;
@Bindable private String userPassword;
public String getToastMessage(){
return toastMessage;
}
public void setToastMessage(String toastMessage)
{
this.toastMessage = toastMessage;
notifyPropertyChanged(BR.toastMessage);
}
public void setUserEmail(String email)
{
user.setEmail(email);
notifyPropertyChanged(BR.userEmail);
}
public String getUserEmail()
{
return user.getEmail();
}
public void setUserPassword(String password)
{
user.setPassword(password);
notifyPropertyChanged(BR.userPassword);
}
public String getUserPassword()
{
return user.getPassword();
}
public LoginViewModel()
{
user = new User("","");
}
public void onLoginClicked() {
if (isInputDataValid())
setToastMessage(successMessage);
else setToastMessage(failedMessage);
}
public boolean isInputDataValid() {
return !TextUtils.isEmpty(getUserEmail()) && Patterns.EMAIL_ADDRESS.matcher(getUserEmail()).matches() && getUserPassword().length() > 5;
}
}
Activity:
package com.javaoneworld.mvvmsample.view;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.BindingAdapter;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.javaoneworld.mvvmsample.R;
import com.javaoneworld.mvvmsample.databinding.ActivityMainBinding;
import com.javaoneworld.mvvmsample.view_model.LoginViewModel;
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
activityMainBinding.setViewModel(new LoginViewModel());
activityMainBinding.executePendingBindings();
}
@BindingAdapter({"toastMessage"})
public static void runMe(View view, String message) {
if (message != null)
Toast.makeText(view.getContext(), message, Toast.LENGTH_SHORT).show();
}
}






529541E7B0
ReplyDeletebot takipçi instagram
chita swivel accent chair
C0521B46AA
ReplyDeleteGörüntülü Sex
Görüntülü Sex
Skype Show Sitesi
F2EAAF1B
ReplyDeleteMuğla
Rize
Sivas
Bolu
Manisa
Karabük
Edirne
Tokat
Düzce
8908EB12
ReplyDeleteBodrum
Konyaaltı
Birecik
Ezine
Osmangazi
Hendek
Mudanya
Sorgun
Çubuk
9297FD7B
ReplyDeleteBiga
Kemer
Kartepe
Ortaköy
Kalkan
Turgutreis
Dikmen
Aliağa
Hopa