This document discusses MVVM and data binding in Android development. It begins with an overview of MVVM theory and the roles of the model, view, and view model. It then covers Android's data binding library for linking UI components to data sources, including features like variable binding, listeners, and view model composition. The document also provides examples of using data binding with RecyclerView and accessing view values directly. It concludes with some links for further reading on MVVM patterns.
2. Agenda
• Theory of MVVM
• Data Binding Library
• Custom MVVM(C) implementation
• View Model Composition
• Binding & RecycleView
• Grabbing value directly from View
• Links
3. Theory of MVVM
• "MVVM facilitates a separation of development of the graphical user interface from development of the
business logic. The view model of MVVM is a value converter; meaning the view model is responsible for
exposing (converting) the data objects from the model in such a way that objects are easily managed and
presented. In this respect, the view model is more model than view, and handles most if not all of the
view's display logic. The view model may implement a mediator pattern, organizing access to the back-
end logic around the set of use cases supported by the view.” (Wikipedia)
• Model - Business data layer, it could be set of POJO objects or layer operating on database/network/
cache. Must be independent of user interface.
• View - User interface.
• View Model - It is responsible for converting data between Model and View, visibility of View components.
4. Data Binding Library
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityBinding binding;
binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
User user = new User("Test", "User");
binding.setUser(user);
}
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout ...>
<TextView
android:text="@{user.firstName}"/>
<TextView
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
BY EXAMPLE
Android Plugin for Gradle 2.1+
https://developer.android.com/topic/libraries/data-binding/index.html
6. Data Binding Library
Widgets are available by binding.id expression, where
id is equal to content of android:id attribute. However,
android:id is not obligatory at all.
<TextView android:id=“@+id/someTextView" />
ActivityMainBinding binding = DataBindingUtil.setContentView(
this, R.layout.activity_main);
binding.someTextView.setText("XYZ");
FEATURE 2 / 15
7. Data Binding Library
Setting almost every widget XML attribute is
possible. Directly by setter paired with attribute like
android:enabled and view.setEnabled(boolean). Or
indirectly using BindingAdapter or BindingMethods.
<EditText
android:enabled=“@{viewModel.enabled}" />
FEATURE 3 / 15
8. Data Binding Library
Observable variables. Every data change could be
reflected to View. "You can change your data model in
a background thread as long as it is not a collection."
public class BaseViewModel extends BaseObservable {
private boolean enabled;
public void setEnabled(boolean enabled) {
this.enabled = enabled;
notifyPropertyChanged(BR.enabled);
}
@Bindable
public boolean getEnabled() {
return enabled;
}
}
<EditText
android:enabled=“@{viewModel.enabled}" />
FEATURE 4 / 15
9. Data Binding Library
Two-way data binding allows synchronization
widget's state between user interface and passed
variable. Main restriction is XML attribute must
have listener indicating change of value.
<EditText
android:text="@={viewModel.value}" />
FEATURE 5 / 15
10. Data Binding Library
EventHandling::MethodReference
• "listener implementation is created when the data is bound”
• "expression is processed at compile time, so if the method does not exist or its signature is not
correct, you receive a compile time error.”
• "method must match the parameters of the event listener”
<Button
android:onClick="@{viewModel::onButtonClick}” />
public void onButtonClick(View view) {
// Some action
}
FEATURE 6 / 15
11. Data Binding Library
() -> EventHandling.ListenerBindings()
• "listener implementation is created when event is triggered”
• "return value must match the expected return value of the listener (unless it is
expecting void)”
<Button
android:onClick=“@{() -> viewModel.onButtonClick()}” />
public void onButtonClick() {
// Some action
}
FEATURE 7 / 15
12. Data Binding Library
BindingAdapter allows to set any data using custom
XML attribute. The same solution helps to write
attributes for custom widgets. No more attrs.xml
files!
@BindingAdapter({"errorEnabled"})
public static void errorEnabled(TextInputLayout view, String value) {
view.setError(value);
view.setErrorEnabled(!TextUtils.isEmpty(value));
}
<android.support.design.widget.TextInputLayout
bind:errorEnabled="@{viewModel.valueError}">
FEATURE 8 / 15
13. Data Binding Library
BindingMethods "Some attributes have setters that
don't match by name… For example, the
android:tint attribute is really associated with
setImageTintList(ColorStateList), not setTint."
@BindingMethods({
@BindingMethod(
type = "android.widget.ImageView",
attribute = "android:tint",
method = "setImageTintList")
})
FEATURE 9 / 15
14. Data Binding Library
Converter helps to translate given value format into
format which is expected by specific XML tag.
@BindingConversion
public static ColorDrawable convertColorToDrawable(String color) {
return new ColorDrawable(Color.parseColor(color));
}
<LinearLayout
android:background="@{viewModel.color}">
FEATURE 10 / 15
15. Data Binding Library
In custom XML attributes we can use application
resources.
<TextView
bind:textColor="@{@color/green}" />
<resources>
<color name="green">#009900</color>
</resources>
FEATURE 11 / 15
17. Data Binding Library
Including layouts. More in View Model Composition
section.
<include
layout="@layout/text_view"
android:layout_width=“match_parent"
android:layout_height=“wrap_content"
bind:viewModel="@{viewModel.redDesc}"
bind:textColor="@{@color/red}" />
FEATURE 13 / 15
18. Data Binding Library
Immediate Binding. "When a variable or observable
changes, the binding will be scheduled to change
before the next frame...To force execution, use the
executePendingBindings() method."
binding.executePendingBindings();
FEATURE 14 / 15
19. Data Binding Library
Data Binding doesn't use reflection. Binding classes
are generated almost in real time by Android Studio,
and they are part of application. You can find them in
build directory.
.../build/intermediates/classes/debug/package_name/databinding/*
FEATURE 15 / 15
20. Custom MVVM(C) implementation
• Bases on Data Binding Library and RxJava
• Layers:
• Model - business data layer (POJO, Database, Cache,
Backend)
• View - user interface (XML and Binding)
• View Model - conversion between displayed data and stored
data (model), validation of forms, etc…
• What’s about Activity and Fragment? Is it View or View Model?
• Or maybe MVVMC? Where:
• Controller - is responsible for global actions like open new
Activities
• View Model - takes care about operation on single screen
https://github.com/wtopolski/androidmvvm
21. View Model Composition
Real app screens are complicated. Usually they
contain several input and output widgets like
EditText, Button, SeekBar, RecycleView, etc.
It would be useful to create set of Views and View
Models. And then reuse them to composite user
interface.
26. Binding & RecycleView
We have to remember that this kind of screen has two sets of
MVVM elements. One for list screen itself. And one for every item
on the list.
colors = generateColors();
adapter = new ColorListAdapter(colors,
getApplicationContext(), this);
ActivityColorListBinding binding;
binding = DataBindingUtil.setContentView(this,
R.layout.activity_color_list);
ColorListViewModel viewModel = new ColorListViewModel();
binding.setViewModel(viewModel);
viewModel.configure(true,
new DefaultItemAnimator(),
new LinearLayoutManager(this));
viewModel.setAdapter(adapter);
https://github.com/wtopolski/androidmvvm
27. Binding & RecycleView
More interesting is MVVM for list elements. First of
all, our adapter is much more simple. No more
custom ViewHolders for RecycleView. All we need is
BindingViewHolder.
public class BindingViewHolder extends RecyclerView.ViewHolder {
private ViewDataBinding binding;
public BindingViewHolder(@NonNull ViewDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public ViewDataBinding getBinding() {
return binding;
}
}
28. Binding & RecycleView
onCreateViewHolder
@Override
public BindingViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
ActivityColorListItemBinding binding = DataBindingUtil.inflate(
LayoutInflater.from(parent.getContext()),
R.layout.activity_color_list_item,
parent,
false);
return new BindingViewHolder(binding);
}
29. Binding & RecycleView
onBindViewHolder
@Override
public void onBindViewHolder(BindingViewHolder holder, int position) {
ActivityColorListItemBinding binding = (ActivityColorListItemBinding)
holder.getBinding();
ColorListItemViewModel viewModel = binding.getViewModel();
// Init new view model object
if (viewModel == null) {
viewModel = new ColorListItemViewModel();
binding.setViewModel(viewModel);
binding.setTextColor(ContextCompat.getColor(context, R.color.colorAccent));
viewModel.setListener(listener);
}
ColorForm form = data.get(position);
viewModel.setAdapterPosition(holder.getAdapterPosition());
viewModel.setData(form);
// Immediate Binding
binding.executePendingBindings();
}
30. Grabbing value directly from View
Getting value from View which is not available in
ViewModel.
private void checkEnabledStateOnView() {
viewModel.confirm.setEditableObserver(new Subscriber<Boolean>() { . . .
@Override
public void onNext(Boolean isEnabled) {
// Some code
}
});
binding.executePendingBindings();
}
bind:editableObserver="@{viewModel.editableObserver}"
@BindingAdapter({"editableObserver"})
public static void editableObserver(View view, Subscriber<Boolean> subscriber) {
if (subscriber != null) {
subscriber.onNext(view.isEnabled());
subscriber.onCompleted();
}
}
31. Links
• MVC VS. MVP VS. MVVM
• Model–view–viewmodel
• Approaching Android with MVVM
• Going with MVVM on Android via Data Binding
• DataBinding: how to develop Android apps faster
• Data Binding Library
• Exploring the MVC, MVP, and MVVM design patterns
• MVVMC thought experiment
• MVVM is dead, long live MVVMC!
• Comparison of Architecture presentation patterns MVP(SC),MVP(PV),PM,MVVM and MVC
• MVMMC – MVVM Grows A Controller