Data binding with MVVM
Agenda
What is MVVM?
Model
View
ViewModel
How to achieve it?
Android data binding
Get started with data binding
Any other benefit?
Boilerplate code
TextView textView = findViewById(R.id.txv_user_name);
textView.setText(model.getUserName());
Boilerplate code
EditText editText = findViewById(R.id.edt_username);
model.setUserName(editText.getText().toString());
Reduced Code with data binding
<TextView
android:text="@{viewModel.userName}"/>
Reduced Code with data binding
<EditText
android:text="@={viewModel.username}"/>
Login Page Example
Login Page Example
Model
Model
public class LoginForm {
public String username;
public String password;
}
Model
public boolean isUsernameValid() {
return !TextUtils.isEmpty(username) && username.length() >= 4;
}
public boolean isPasswordValid() {
return !TextUtils.isEmpty(password) && password.length() >= 4;
}
Login Page Example
ViewModel
ViewModel
public class LoginViewModel {
public LoginForm loginForm = new LoginForm();
public void onLoginClick() {
isValid();
}
}
ViewModel
private boolean isValid() {
boolean passwordValid = loginForm.isPasswordValid();
boolean usernameValid = loginForm.isUsernameValid();
return usernameValid && passwordValid;
}
Login Page Example
View
View
<layout>
<data>
<variable name="loginViewModel"
type="com.example.viewModel.LoginViewModel"/>
</data><!--View root layout-->
</layout>
View
<EditText
android:id="@+id/edt_username"
android:text="@={loginViewModel.loginForm.username}"/>
<EditText
android:id="@+id/edt_password"
android:text="@={loginViewModel.loginForm.password}"/>
View
<Button
android:id="@+id/btn_login"
android:onClick="@{() -> loginViewModel.onButtonClick()}"/>
Login Page Example
ViewModel
public LoginForm loginForm = new LoginForm();
public ObservableField<String> usernameError =
new ObservableField<>();
public ObservableField<String> passwordError =
new ObservableField<>();
ViewModel
if (!usernameValid){
usernameError.set("Please enter valid username");
}
if (!passwordValid){
passwordError.set("Please enter valid password");
}
ViewModel
@BindingAdapter("error")
public static void setError(EditText editText, String error) {
editText.setError(error);
}
View
<EditText
android:id="@+id/edt_username"
app:error="@{loginViewModel.usernameError}"/>
<EditText
android:id="@+id/edt_password"
app:error="@{loginViewModel.passwordError}"/>
How view is connected to ViewModel?
Connect DataBinding and ViewModel
setContentView(R.layout.activity_login);
Connect DataBinding and ViewModel
setContentView(R.layout.activity_login);
ActivityLoginBinding loginBinding = DataBindingUtil.setContentView(this, R.layout.activity_login);
LoginViewModel loginViewModel = new LoginViewModel();
loginBinding.setLoginViewModel(loginViewModel);
Recap..
Recap..
Recap..
Recap..
Recap..
Observable Objects
Observable Objects
ViewModel
public class LoginViewModel extends BaseObservable {
private String userName;
@Bindable
public String getUserName() {
return userName;
}
}
ViewModel
public void onLoginClick() {
if (isValid()) {
userName = "Test user name";
notifyPropertyChanged(BR.userName);
}
}
LiveData
LiveData
ViewModel
public class LoginViewModel {
private MutableLiveData<String> userNameLiveData =
new MutableLiveData<>();
public MutableLiveData<String> getUserNameLiveData() {
return userNameLiveData;
}
}
ViewModel
public void onLoginClick() {
if (isValid()) {
userNameLiveData.setValue("Test name");
}
}
Activity
Observer<String> observer = new Observer<String>() {
@Override
public void onChanged(@Nullable String username) {
Toast.makeText(LoginActivity.this, username,
Toast.LENGTH_SHORT).show();
}
};
Activity
loginViewModel.getUserNameLiveData().observe(this, observer);
Questions??
Thank You