Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MVVM & Data Binding Library

1,832 views

Published on

Read presentation about MVVM & Data Binding Library written by our Android Developer, Wojciech Topolski from 10Clouds!

Published in: Technology
  • Be the first to comment

MVVM & Data Binding Library

  1. 1. MVVM & Data Binding Library Wojciech Topolski
  2. 2. Agenda • Theory of MVVM • Data Binding Library • Custom MVVM(C) implementation • View Model Composition • Binding & RecycleView • Grabbing value directly from View • Links
  3. 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. 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
  5. 5. Data Binding Library Variables and imports in <data>...</data> section.
 <?xml version="1.0" encoding="utf-8"?>
 <layout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:bind="http://schemas.android.com/apk/res-auto">
 <data>
 <import type="android.view.View" />
 <variable
 name="viewModel"
 type="com.github.wtopolski.libmvvm.viewmodel.ButtonViewModel"/>
 </data>
 
 <Button . . . />
 
 </layout> FEATURE 1 / 15
  6. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  16. 16. Data Binding Library Null Coalescing Operator <TextView
 android:text=“@{user.displayName ?? user.lastName}” /> FEATURE 12 / 15
  17. 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. 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. 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. 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. 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.
  22. 22. View Model Composition
  23. 23. View Model Composition SeekBar View <?xml version="1.0" encoding="utf-8"?>
 <layout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:bind="http://schemas.android.com/apk/res-auto">
 <data>
 <import type="android.view.View" />
 <variable
 name="viewModel"
 type="com.github.wtopolski.libmvvm.viewmodel.SeekBarViewModel"/>
 </data>
 
 <SeekBar
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:max="@{viewModel.max}"
 android:progress="@={viewModel.progress}"
 android:visibility="@{viewModel.visibility ? View.VISIBLE : View.GONE}"
 android:enabled="@{viewModel.enabled}" />
 
 </layout>
  24. 24. View Model Composition SeekBar View Model public class SeekBarViewModel extends BaseViewModel {
 private int progress;
 private int max;
 private PublishSubject<Integer> progressObservable = PublishSubject.create();
 
 public SeekBarViewModel() { super(); }
 
 public SeekBarViewModel(boolean enabled, boolean visibility) { super(enabled, visibility); }
 
 public void setProgress(int progress) {
 this.progress = progress;
 progressObservable.onNext(progress);
 notifyPropertyChanged(BR.progress);
 }
 
 @Bindable
 public int getProgress() { return progress; }
 
 public void setMax(int max) {
 this.max = max;
 notifyPropertyChanged(BR.max);
 }
 
 @Bindable
 public int getMax() { return max; }
 
 public Observable<Integer> rxProgress() { return progressObservable.asObservable(); }
 }
  25. 25. View Model Composition activity_color_form.xml ColorFormViewModel.java
  26. 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. 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. 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. 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. 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. 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

×