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

Implements MVVM in Android with Data-binding

Elvis Lin
December 19, 2016

Implements MVVM in Android with Data-binding

Demonstrate how to use Data-binding to implement MVVM in Android

Elvis Lin

December 19, 2016
Tweet

More Decks by Elvis Lin

Other Decks in Programming

Transcript

  1. @Override
 public void onLoad() {
 Capital capital 
 = capitalModel.getCapital;


    String displayCapital = 
 capital.getCity()
 + “, ”
 + capital.getNation();
 
 // Update UI
 view.setCapital(displayCapital);
 }
  2. But, do we really need it? class IPresenter { void

    onLoad() {
 …
 view.setCapital(displayCapital);
 }
 
 }
  3. 狕硬 Layout file <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable

    name="user" type="com.example.User"/> </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <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}"/> </LinearLayout> </layout>
  4. <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android=“http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.User"/> </data>

    <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <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}"/> </LinearLayout> </layout>
  5. <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.User"/> </data>

    <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height=“match_parent"> <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}"/> </LinearLayout> </layout>
  6. 碝ी Data Object public class User { public final String

    firstName; public final String lastName; public User(
 String firstName, 
 String lastName) { this.firstName = firstName; this.lastName = lastName; } } public class User { private final String firstName; private final String lastName; public User(
 String firstName,
 String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return this.firstName; } public String getLastName() { return this.lastName; } } ොဩӞ ොဩԫ
  7. 翉ਧᇔկ • 䌘ෝPDLQBDFWLYLW\[PO䨝叨ኞ0DLQ$FWLYLW\%LQGLQJጱ ᇔկ • 翉ਧ盅'DWDጱ独疰䨝ๅ碝/D\RXW䌘䛑ጱ痀௔ @Override protected void onCreate(Bundle

    savedInstanceState) { super.onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil.setContentView( this, R.layout.main_activity); User user = new User("Test", "User"); binding.setUser(user); }
  8. UIԪկ蒂ቘ public class MyHandlers { public void onClickFriend(View view) {

    ... } } <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="handlers" type="com.example.Handlers"/> <variable name="user" type=“com.example.User"/> </data> <LinearLayout …… > <TextView …… android:text="@{user.firstName}" android:onClick=“@{handlers::onClickFriend}"/> </LinearLayout> </layout>
  9. UIԪկ蒂ቘ — Lambda <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable

    name="task" type="com.android.example.Task" /> <variable name="presenter" type="com.example.MyHandler" /> </data> <LinearLayout android:layout_width=“match_parent” android:layout_height=“match_parent"> <Button android:layout_width=“wrap_content" android:layout_height=“wrap_content" android:onClick="@{() -> MyHandler.onSaveClick(task)}" /> </LinearLayout> </layout>
  10. 櫕ݻ翉ਧ • ইຎݝฎ蝚螂 Binding 䁆ᤈ setUser牧吚 User ᇔկ ጱ独虋㵕碻牧/D\RXW 㪔犋䨝ๅ碝

    • 蝢Ꭳ Layout ๅ碝ጱොୗ • Observable Objects • Observable Fields • Observable Collections
  11. Observable Objects private static class User extends BaseObservable { private

    String firstName; private String lastName; @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } }
  12. Observable Objects private static class User extends BaseObservable { private

    String firstName; private String lastName; @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } }
  13. Observable Fields private static class User { public final ObservableField<String>

    firstName = new ObservableField<>(); public final ObservableField<String> lastName = new ObservableField<>(); public final ObservableInt age = new ObservableInt(); }
  14. 狕硬 View ጱ Layout file • ࣁ/D\RXWƉOHӾےӤYLHZ0RGHOጱ虋碍 <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"> <data> <variable name=“viewModel" type="edu.self.scoredbmvvm.viewmodel.SearchViewModel"/> </data> <LinearLayout …… > </LinearLayout> </layout>
  15. ࣁ ViewModel ےӤ ObservalField public class SearchViewModel { public ObservableField<String>

    userScore = new ObservableField<>(); …. public SearchViewModel(Context context) {} public void searchScore() { // do searching and modify userScore } public TextWatcher getUserNameEditTextWatcher() { return new TextWatcher() { .... }; }
  16. ࣁ ViewModel ےӤ 䌘䛑ጱ蒂ቘ獢碍 public class SearchViewModel { public ObservableField<String>

    userScore = new ObservableField<>(); …. public SearchViewModel(Context context) {} public void searchScore() { // do searching and modify userScore } public TextWatcher getUserNameEditTextWatcher() { return new TextWatcher() { .... }; }
  17. 翉ਧ ViewModel 蚤 
 Layout ጱ痀௔独 <LinearLayout .... > <EditText

    .... app:addTextChangedListener= "@{viewModel.userNameEditTextWatcher}"/> <Button .... android:onClick="@{() -> viewModel.searchScore()}"/> </LinearLayout> <TextView .... android:text="@{viewModel.userScore}"/>
  18. 虏 ViewModel 蚤 Model 传蝢 public class SearchViewModel extends BaseObservable{

    .... public void searchScore() { new AsyncTask<String, Void, Long>() { .... @Override protected Long doInBackground(String... strings) { return SearchScoreManager.getInstance().
 searchScoreForLongTime(strings[0]); } @Override protected void onPostExecute(Long score) { .... userScore.set(score == null ? "not exist" : score.toString()); } }.execute(userName); } }
  19. 奾抷 • 橕ဳ讨獤櫝ҁSeparation of Concerns ) • MVVM 虏 View

    蚤 ViewModel 櫕ݻ翉ਧ • View ݝ揗揣虻碘ጱ氥纈蚤UIԪկ㯽螏 • View ጱๅ碝ݢ犥蝚螂 RxJava ౲ Data binding ਠ ౮
  20. Contact Info Elvis Lin • Github: 
 https://github.com/elvismetaphor • Blog:

    http://article.elvismetaphor.me • Slides: https://speakerdeck.com/ elvismetaphor