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

Working with databinding

Working with databinding

Prasham Trivedi

January 09, 2016
Tweet

More Decks by Prasham Trivedi

Other Decks in Programming

Transcript

  1. MVC • Model - Container for your business data. •

    View - Something that shows model data to end user. • Controller
  2. MVC • Model - Container for your business data. •

    View - Something that shows model data to end user. • Controller - Controls how model data goes to view and how view is affected by model data.
  3. MVC • Model - Regular JavaBeans • View - Activities*,

    Views, Xml • Controller - Activities*, Network layer, DB layer. Activities* - Also fragments since ICS In Android since v1.0
  4. MVVM • Stands for Model, View, ViewModel • Adds functionality

    to Controller of MVC, and make it modular • Does not (entirely) replace role of activities and fragments as controller. • ViewModel defines rule of handling views based on Model. • Leaving controlling part - (Db, Network screen routing) on activities and fragments.
  5. DataBinding • Introduced In Google I/O 2015. • Started with

    android gradle plugin v1.3.0 (Probably), required separate plugin. • Merged with main plugin android gradle plugin v1.5.0
  6. Databinding-Setup • In your project’s build.gradle file, add/upgrade your android

    plugin to v1. 5 classpath 'com.android.tools.build:gradle:1.5.0' • In your module’s build.gradle file update your android{} dsl with databinding.enabled=true android { // Other Logic dataBinding { enabled = true } // Other Logic }
  7. Before Databinding 1- Layouts <LinearLayout ...> <LinearLayout ...> <android.support.design.widget.TextInputLayout ...>

    <EditText android:id="@+id/userNameEditText" .../> </android.support.design.widget.TextInputLayout> <Button android:id="@+id/btnSendVerification" .../> </LinearLayout> </LinearLayout>
  8. Before Databinding 1- Layouts <LinearLayout ...> <LinearLayout ...> <android.support.design.widget.TextInputLayout ...>

    <EditText android:id="@+id/userNameEditText" .../> </android.support.design.widget.TextInputLayout> <Button android:id="@+id/btnSendVerification" .../> </LinearLayout> </LinearLayout>
  9. Before Databinding 2- Java @Override protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); EditText userName = (EditText) findViewById(R.id.userNameEditText); Button sendVerification = (Button) findViewById(R.id. btnSendVerification); sendVerification.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //TODO: Check username is null or not //TODO: Send it to webservice, (if network is there, otherwise save somewhere to send it later) } }); }
  10. Problems • Too much coding. • Too much checks. •

    Error prone. • Butterknife to the rescue • But works on findViewById • Also crashes if error is there
  11. Databinding to the rescue • No FindViewBy ids. • Cast

    automatically. • Can bind properties directly from xml to java code.
  12. After Databinding 1- Layouts <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="login" type="com.celites.aamantran.ViewModels.LoginViewModel"/>

    </data> <LinearLayout ...> <LinearLayout ...> <android.support.design.widget.TextInputLayout ...> <EditText android:id="@+id/userNameEditText" android:hint="@{login.userName}" .../> </android.support.design.widget.TextInputLayout> <Button android:onClick="@{login.verify}" android:id="@+id/btnSendVerification" .../> </LinearLayout> </LinearLayout> </layout>
  13. Before Databinding 1- Layouts <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="login" type="com.celites.aamantran.ViewModels.LoginViewModel"/>

    </data> <LinearLayout ...> <LinearLayout ...> <android.support.design.widget.TextInputLayout ...> <EditText android:id="@+id/userNameEditText" android:hint="@{login.userName}" .../> </android.support.design.widget.TextInputLayout> <Button android:onClick="@{login.verify}" android:id="@+id/btnSendVerification" .../> </LinearLayout> </LinearLayout> </layout>
  14. After Databinding 2- Java @Override protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_login); viewModel = new LoginViewModel(this); binding.setLogin(viewModel); setSupportActionBar(binding.toolBar); }
  15. After Databinding 2- Java @Override protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_login); viewModel = new LoginViewModel(this); binding.setLogin(viewModel); setSupportActionBar(binding.toolBar); }
  16. Button Click Listener. public OnClickListener getVerify() { return verify; }

    OnClickListener verify = new OnClickListener() { @Override public void onClick(View v) { startLogin(); } } };
  17. Working with properties- Defaults • In Xml <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"

    android:text="@{user.firstName}"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.lastName}"/> • In Java - User Class public class User { public final String firstName; public final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } }
  18. • In Java - Binding MainActivityBinding binding = DataBindingUtil. setContentView(this,

    R.layout.main_activity); User user = new User("Test", "User"); binding.setUser(user);
  19. Rules • Binding Class name = Layout Pascal case name

    + Binding ◦ For layout activity_place_details, binding class name is ActivityPlaceDetailsBinding • For each variable, you need to set data. • For each property, there must be a public getter equivalent to it ◦ E.g. for @{user.firstName} there must be public variable or public getter for it
  20. Two-Way binding* • Only one way binding. From Java to

    Xml. • For Read only presentation. • Can not read-validate form • Can not update status based on child/sibling view’s property *- By default, However it’s possible *
  21. Two-Way binding • By Observables ◦ Not Rx.Observables • Getters

    and setters by default • Runs thread safe • Can bind with existing views.
  22. @BindingAdapter({"binding"}) public static void bindSwitch(CompoundButton button, final BindableBoolean bindableBoolean) {

    button.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { bindableBoolean.set(isChecked); } }); boolean isChecked = bindableBoolean.get(); if (button.isChecked() != isChecked) { button.setChecked(isChecked); } }
  23. @BindingAdapter(value = {"visibleIf", "inverse"}, requireAll = false) public static void

    changeViewDependency(View view, BindableBoolean bool, boolean inverse) { int visibility = bool.get() ? View.VISIBLE : View.GONE; int visibilityInverse = bool.get() ? View.GONE : View.VISIBLE; view.setVisibility((inverse) ? visibilityInverse : visibility); }
  24. /** * Created by Prasham on 10/14/2015. */ public class

    BindableBoolean extends BaseObservable { boolean mValue; public boolean get() { return mValue; } public void set(boolean value) { if (mValue != value) { this.mValue = value; notifyChange(); } } }
  25. BindingAdapter and Observables • Public getters and setters required •

    Get to read value. Set to right value. • Nearly thread safe • Static methods - Errors on duplicate implementation • Single method can listen to multiple attributes. @BindingAdapter Annotation • Can convert from one object to another @BindingConversion Annotation
  26. Custom attributes-Picasso example @BindingAdapter({"bind:imageUrl", "bind:error"}) public static void loadImage(ImageView view,

    String url, Drawable error) { Picasso.with(view.getContext()).load(url).error(error).into(view); } <ImageView app:imageUrl=“@{venue.imageUrl}” app:error=“@{@drawable/venueError}”/>
  27. Databinding- As ViewModel • Create a ViewModel from our model

    • Define view rules in view model and expose them as getters • Use view models in xml and refer to rules • Set BindingAdapters, BindingConversions to establish a rule • And again, one binding adapter should be common for whole project
  28. One-way and two-way • One way binding for view only

    adapter rows • Two way binding for forms and views with dynamic behavior
  29. Tips and Tricks • Custom fontfaces using databinding - tip

    from Lisa Wray - https://plus.google. com/+LisaWrayZeitouni/posts/LTr5tX5M9mb • Visibility using Boolean - Tip From Lisa Wray - https://plus.google. com/+LisaWrayZeitouni/posts/5DQGiNbne5W • Tinting - Tip from Luis G Vale - https://plus.google.com/+LuisGonz%C3% A1lezValle/posts/YjUcVJ14Rf5 • Datepicker databinding - George Mount ( A googler) https://halfthought.wordpress. com/2015/10/16/datepicker-data-binding/ • RTL Support - Yours truly - https://plus.google.com/+PrashamTrivedi/posts/gCxFGLV498h