Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[Roman Herasymenko] Deal with it: Android DataBinding explained

[Roman Herasymenko] Deal with it: Android DataBinding explained

Presentation from GDG DevFest Ukraine 2016.
Learn more at: https://devfest.gdg.org.ua

Google Developers Group Lviv

September 10, 2016
Tweet

More Decks by Google Developers Group Lviv

Other Decks in Technology

Transcript

  1. #dfua Model-View-Controller Controller layer - (Activity/Fragment), aware both of the

    View and Model Model layer - same as the Controller layer View - XML layout only
  2. #dfua Model-View-Presenter DataManager - model layer, holds a reference to

    Retrofit, Database, etc. Presenter Layer - in the “middle” between View layer and Model Layer, doesn’t know anything about Activity/Fragment/View View Layer - combination of Activity/Fragment with implementation of the View interface and XML layout. Holds soft reference to Presenter.
  3. #dfua What is the difference? Controller - replaced by ViewModel,

    and located below UI layer ViewModel - exposes the data and command objects for the View ViewModel - receives its data from the Model layer Model - business and validation
  4. #dfua public class UserViewModel extends BaseObservable {
 
 private UserInteractor

    interactor;
 private String username;
 
 public UserViewModel(UserInteractor interactor, long id) {
 this.interactor = interactor;
 if (id != WRONG_ID) loadUserById(id);
 }
 
 public final TextWatcher usernameWatcher = new TextWatcherAdapter() {
 @Override
 public void afterTextChanged(Editable s) {
 username = TextUtils.isEmpty(s)? “” : s.toString();
 notifyPropertyChanged(co.yamert.binding.BR.username);
 }
 };
 
 @Bindable
 public String getUsername() {
 return username;
 }
 }
 ViewModel
  5. #dfua public class UserFragment extends Fragment implements UserInteractor {
 


    @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
 
 UserBinding binding = DataBindingUtil.inflate(R.layout.fragment_user);
 UserViewModel vm = new UserViewModel(this, id);
 binding.setViewModel(vm); 
 return binding.getRoot();
 }
 
 @Override
 public void onDialogButton() {
 Intent intent = new Intent();
 startActivity(intent);
 }
 } Bring it all together
  6. #dfua public class ColorPicker extends View {
 private int color;


    
 public ColorPicker(Context context) {
 super(context);
 }
 
 public void setColor(int color) {
 this.color = color;
 invalidate();
 }
 
 public void addListener(OnColorChangeListener listener) { }
 
 public void removeListener(OnColorChangeListener listener) { }
 } Custom setter
  7. #dfua public class BindingAdapters {
 
 @BindingAdapter("color")
 public static void

    setPickerColor(ColorPicker picker, int color) {
 if (picker != null)
 picker.setColor(color);
 }
 } Binding adapter as setter
  8. #dfua @BindingAdapter("onColorChange")
 public static void setColorChangeListener(ColorPicker view, OnColorChangeListener oldListener, OnColorChangeListener

    newListener) {
 
 if (oldListener != null)
 view.removeListener(oldListener);
 
 if (newListener != null)
 view.addListener(newListener);
 } Events handling
  9. #dfua @BindingAdapter({"bind:font"})
 public static void setFont(TextView textView, String fontName) {


    textView.setTypeface(Typeface.createFromAsset(textView .getContext() .getAssets(), "fonts/" + fontName));
 } <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 app:font="@{'Roboto-Regular.ttf'}" /> Tip: Fonts binding
  10. #dfua @BindingAdapter(value = {"imageUrl", "placeholder"}, requireAll = false)
 public static

    void setImageUrl(ImageView imageView, String url, Drawable placeHolder) {
 if (url == null) {
 imageView.setImageDrawable(placeholder);
 } else {
 ImageLoader.loadInto(imageView, url, placeholder);
 }
 } Binding adapter
  11. #dfua @BindingAdapter("usersList")
 public static void setUsersList(RecyclerView recycler, List<User> users) {


    if (recycler.getAdapter() != null)
 return;
 
 Context context = recycler.getContext();
 LinearLayoutManager manager = new LinearLayoutManager(context);
 manager.setOrientation(LinearLayoutManager.HORIZONTAL);
 recycler.setLayoutManager(manager);
 recycler.setHasFixedSize(true);
 recycler.setAdapter(new UserAdapter(users));
 } Binding adapter
  12. #dfua <View
 android:background="@{isError ? @color/red : @color/white}"
 android:layout_width="wrap_content"
 android:layout_height=“wrap_content"/> 


    @BindingConversion
 public static ColorDrawable convertColorToDrawable(int color) {
 return new ColorDrawable(color);
 } Binding conversion