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

Implements MVVM in Android with Data-binding

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Elvis Lin Elvis Lin
December 19, 2016

Implements MVVM in Android with Data-binding

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

Avatar for Elvis Lin

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