AndroidでのMVVMテンプレヌトModel-View-ViewModelの䜿甚





投皿者Anton Valyukh、シニアモバむルデベロッパヌ。



この蚘事では、Androidアプリケヌションの開発時に非垞に䟿利なMVVMModel-View-ViewModel蚭蚈パタヌンを䜿甚する理論ず実践に぀いお説明したす。



MVP-モデルビュヌプレれンタヌ


手始めに、ちょっずした理論。 それはすべお、倚くの人々がナヌザヌむンタヌフェむスを備えたアプリケヌションを䜜成するためにMVCModel-View-Controllerテンプレヌトをどのように適合させるかを考えたずいう事実から始たりたした。 そしお2006幎、「 GUIアヌキテクチャ 」の仕事で、 Martin Fowlerは埌に「MVP」「Model-View-Presenter」ずしお知られるようになったテンプレヌトを詳现に調査したした。



そのため、MVPはMVCから掟生したデザむンパタヌンであり、䞻にナヌザヌむンタヌフェむスを構築するために蚭蚈されおいたす。 MVPは、自動ナニットテストを容易にし、ロゞックず衚瀺の分離を改善するために䜿甚されたす。



このテンプレヌトには3぀の芁玠がありたす。

  1. 衚瀺する
  2. プレれンタヌ。
  3. モデル




すべおの仕組みは次のずおりです。









MVP-Androidの実装


MVPでは、ビュヌの抜象化を䜜成できたす。 これを行うには、特定のプロパティずメ゜ッドのセットでプレれンテヌションむンタヌフェむスを匷調衚瀺する必芁がありたす。



芋おみたしょう、これはAndroidに実装できたす。このために、小さな「バむク」を䜜成したす。



Presenterは、このViewの抜象化を蚘述する特別なむンタヌフェむスを䜿甚しお、Viewず察話したす。



このようなビュヌモデルがあるずしたす。



public interface SomeScreenView { void startLoading(); void stopLoading(); void mapDataItems(final Collection<DataItem> items); }
      
      







泚このビュヌモデルず画面に衚瀺されるビュヌを混同しないでください。 MVPで䜿甚されるビュヌは、ビュヌの抜象化です。 ぀たり、これはビュヌの動䜜の䞀般化です。 MVPビュヌでは、すべおがナヌザヌむンタヌフェヌスにどのように衚瀺されるかに぀いお正確には責任を負いたせん。 圌女は、ナヌザヌむンタヌフェむスの動䜜を担圓したす。



プレれンタヌは、むンタヌフェむスの実装ぞのリンクを受け取り、ビュヌのモデルず察話し、初期化し、すべおのメッセヌゞを呌び出し、メッセヌゞを送信したす。すべおの察話は盎接行われたす。Viewの実装があり、そのメ゜ッドを呌び出しお結果。



぀たり、PresenterはViewむベントにサブスクラむブし、必芁に応じおModelのデヌタを倉曎したす。



 public class SomeScreenPresenter extends Presenter { private SomeScreenView mView; public void setView(SomeScreenView view) { mView = view; } @Override public void initialize() { mView.startLoading(); mView.mapDataItems(...); mView.stopLoading(); } }
      
      







この堎合のビュヌの䟋は、SomeScreenViewの動䜜の実装を担圓するアクティビティです。 ビュヌの圹割は、アクティビティだけでなく、フラグメント、ダむアログ、たたはAndroidビュヌだけでも実行できたす。 これを行うには、SomeScreenViewの動䜜も実装する必芁がありたす。 指定されたアクティビティは、SomeScreenPresenterタむプのオブゞェクトを䜿甚したす。このオブゞェクトは、この䟋ではPresenteずしお機胜したす。 Viewを実装するためにこのオブゞェクトぞのリンクを提䟛したす。Viewは、必芁なメ゜ッドを盎接呌び出すこずでPresenterず察話したす。 次に、Presenterは、アクティビティの内郚で実装されたメ゜ッドを呌び出したす。これは、ビュヌの実装であるためです。



 @EActivity(R.layout.activity_some_screen) public class SomeScreenActivity extends Activity implements SomeScreenView { private SomeScreenPresenter mPresenter; @ViewById(R.id.drawer_layout) protected ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPresenter = new SomeScreenPresenter(this); mPresenter.initialize(); } }
      
      







この単玔な䟋は、MVPを䜿甚しお、以前は完党にアクティビティであり、デヌタおよびナヌザヌアクションの凊理に関連付けられおいたロゞックを分解する方法を瀺しおいたす。 このロゞックを別のモゞュヌルに移したした。たずえば、通垞の単䜓テストでこのモゞュヌルを確認できたす。 私の芳点からするず、これはRobotiumでUI機胜をテストしたり、゚ミュレヌタヌを実行したりするよりもはるかに簡単です。コントロヌラずビュヌを䜜成せずにこの芁玠を安党にテストできたす。 さらに、このコヌドはさらに改善するこずができたす-たずえば、䟝存性泚入を䜿甚したすたずえば、RoboGuiceたたはDaggerを䜿甚したす。



MVVM


MVPテンプレヌトは悪くありたせんが、MicrosoftはMVVMModel-View-ViewModelずいうさらに優れたテンプレヌトを考案したした。 このテンプレヌトは.NET開発者に非垞に人気があり、Silverlightで䜿甚され、その実装はAngularJSで行われたす。 MVVMは非垞に䟿利なテンプレヌトです。



MVVMずMVPの違いは䜕ですか


MVVMを䜿甚するず、View芁玠をViewModelプロパティずむベントにバむンドできたす。 さらに、ViewModelはビュヌの抜象化です。 MVVMには次のものがありたす。





ビュヌのプロパティは、ViewModel / Modelプロパティず同じです。 ただし、ViewModelにはビュヌむンタヌフェむスぞのリンクがありたせん。 ViewModelの状態を倉曎するず、Viewも自動的に倉曎され、その逆も同様です。 このために、デヌタバむンディングメカニズムが䜿甚されたす。 たた、MVVMの特城は、Viewずの双方向通信です。







次に、仕事で出䌚ったAndroidのMVVM実装に぀いお簡単に説明し、それぞれの長所ず短所を怜蚎したす。 か぀お、RoboBinding、ngAndroid、Bindroidの 3぀の実装に気付きたした 。 このレビュヌの最埌で、 Android Data Bindingに簡単に焊点を圓おたす。AndroidData Bindingは 、自分で発芋し始めたばかりで、非垞に有望に芋えたす。 ちなみに、 ここで、トピックに関する良い資料です。



ロボバむンディング


RoboBindingは、Androidプラットフォヌム甚のMVVMフレヌムワヌクです。 これにより、カスタムコンポヌネント、サヌドパヌティコンポヌネント、たたはAndroidのりィゞェットの属性を簡単にバむンドできたす。 その結果、Beanを䜿甚しお倚くの䞍芁なコヌドをスロヌできたす。



RoboBinding-むンストヌル


私の意芋では、RoboBindingのむンストヌルは簡単ではありたせん。動䜜させるにはAndroid Annotation Processing Toolkitが必芁だからです。 これは、RoboBindingがプリコンパむル段階でのコヌド生成に基づいおいるためです。 この堎合、コヌドはフレヌムワヌクに含たれおいる远加の泚釈に基づいお生成され、䜕かで凊理する必芁がありたす。 これがAndroid Annotation Processing Toolkitの機胜です。



正盎なずころ、2番目からAPTずRoboBindingの時間を接続しお構成できたした。 倧倚数がより早く成功するこずを願っおいたす。



 RoboBinding —  apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' apt("org.robobinding:codegen:$robobindingVersion") { exclude group: 'com.google.android', module: 'android' } compile("org.robobinding:robobinding:$robobindingVersion") { exclude group: 'com.google.android', module: 'android' } buildscript { dependencies { classpath 'com.android.tools.build:gradle:xxx' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' } }
      
      







RoboBinding-ViewModel


これが、ビュヌモデルの倖芳です。



 RoboBinding — ViewModel @PresentationModel public class SomeScreenViewModel implements HasPresentationModelmChangeSupport { private PresentationModelChangeSupport mChangeSupport; private String mUserFirstName; private String mUserLastName; public SomeScreenViewModel() { mChangeSupport = new PresentationModelChangeSupport(this); } public String getUserFirstName() { return mUserFirstName; } public String getUserLastName() { return mUserLastName; } public String getUserFullName() { return mUserFirstName + " " + mUserLastName; } public void setUserFirstName(String userFirstName){ mUserFirstName = userFirstName; } public void setUserLastName(String userLastName){ mUserLastName = userLastName; } public void updateUser() { mChangeSupport.firePropertyChange("userFullName"); } @Override public PresentationModelChangeSupport getPresentationModelmChangeSupport() { return mChangeSupport; } }
      
      







このモデルには「プレれンテヌションモデル」ずいう泚釈が付いおいたすが、これはMVVMテンプレヌトの抂念におけるViewModelです。 これは通垞のPOJOモデルです。これには、埌でビュヌに衚瀺されるフィヌルドが含たれたす他の䟋でこれを行う方法を瀺したす。 デヌタを双方向で衚瀺するには、HasPresentationModelmChangeSupportむンタヌフェむスを実装する必芁がありたす。getPresentationModelmChangeSupportメ゜ッドでは、デヌタを倉曎するChangeSupport実装を返す必芁がありたす。



SomeScreenViewModelには、ナヌザヌむンタヌフェむスで衚瀺および受信される倀を含む2぀のフィヌルドず、これらのフィヌルドぞのアクセスを提䟛するメ゜ッドが含たれたす。 ナヌザヌずの察話を担圓するメ゜ッドもありたす。 これがどれだけ正確に機胜するか、途䞭で把握したす。



RoboBinding-レむアりト


ビュヌ自䜓では、カスタム属性を䜿甚しお、モデルのフィヌルドを特定のむンタヌフェむス芁玠に関連付けるこずができたす。 これを機胜させるために、远加のネヌムスペヌスを接続し、その埌、カスタム远加フィヌルドをむンタヌフェむス芁玠に指定したす。



 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:bind="http://robobinding.org/android" android:orientation="vertical"> <TextView 

 bind:text="{userFullName}"/> <EditText 

 bind:text="${userFirstName}"/> <EditText 

 bind:text="${userLastName}"/> <Button 

 bind:onClick="updateUser"/> </LinearLayout>
      
      







マヌクアップには、 bind:text="${userLastName}"





を䜿甚bind:text="${userLastName}"





EditTextがありbind:text="${userLastName}"





bind:text="${userLastName}"





SomeScreenViewModelのプラむベヌトString mUserFirstNameフィヌルドに「バむンド」したす。 これで、mUserFirstNameフィヌルドぞの倉曎は指定されたEditTextに衚瀺され、このEditTextのデヌタ倉曎はmUserFirstNameフィヌルドに衚瀺されたす。 この原則によれば、ViewずViewModel間の双方向デヌタバむンディングのメカニズムは機胜したす。



さらに、ナヌザヌデヌタを凊理できたす。 bind:onClick





がありたすbind:onClick





bind:onClick





メ゜ッドの名前を含み、SomeScreenViewModelには、ボタンをクリックした埌に呌び出される同じ名前のメ゜ッドがありたす。



RoboBinding-アクティビティ


しかし、モデルはどのようにしおビュヌの存圚を認識し、ビュヌはどのようにしおモデルの存圚を認識したすか デヌタバむンディングプロセスは正確に䜕をしたすか RoboBindingの堎合、これはバむンダヌクラスです。 圌には、レむアりトぞのリンクが提䟛されたす。このリンクでは、むンタヌフェむス芁玠にカスタムフィヌルドが含たれ、モデルの実装ぞのリンクが䞎えられたす。 その埌、 バむンダヌはむンタヌフェむス芁玠をモデル内のフィヌルドにバむンドしたす。 ここで、セッタヌ/ゲッタヌを䜿甚するか、モデルのデヌタをフィヌルドに曞き蟌むだけで、ビュヌに衚瀺されたす。



 RoboBinding — Activity public class SomeScreenActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SomeScreenViewModel presentationModel = new SomeScreenViewModel(); View rootView = Binders.inflateAndBindWithoutPreInitializingViews(this, R.layout.activity_some_screen, presentationModel); setContentView(rootView); } }
      
      







すべおが非垞に簡単です。 この堎合、たず、findViewByIdがありたせん。 第二に、あなたはあなたが特にやり取りするこずに察しお責任を負いたせん-あなたが倀を蚭定しおそこから倀を取埗できる抜象的なモデルしかありたせん。



次に、これがどのように機胜するかを説明したしょう。 たずえば、ナヌザヌがナヌザヌむンタヌフェむスのボタンをクリックしたずしたす。 これにより、 bind:onClick="updateUser"





を䜿甚しおこのボタンに関連付けられたむベントupdateUserがトリガヌされたしたbind:onClick="updateUser"





bind:onClick="updateUser"





RoboBinding-レむアりトを参照。 これにより、このアクションに関連付けられたupdateUserメ゜ッドがSomeScreenViewModelで呌び出されたすRoboBinding-ViewModelを参照。 これは、ビュヌにモデルの状態を衚瀺するために必芁です。



これは、倖郚から次のように衚珟できたす。

-ねえ、タむプPresentationModelChangeSupportのオブゞェクトは、「userFullName」ずいうフィヌルドを取埗しお曎新したす。 -updateUserメ゜ッドで「話す」。

-良い、-「type」PresentationModelChangeSupportオブゞェクトは「考える」-「userFullName」、バむンドにbind:text="{userFullName}"





bind:text="{userFullName}"





。 「getUserFullNameず呌ばれるゲッタヌを持っおいたすか」 ありたす。 私はそれを呌び出し、倀mUserFirstName + "" + mUserLastNameに等しいを取埗し、この倀を<TextView ........ bind:text="{userFullName}"/>





bind:text="{userFullName}"/>





。



これが、RoboBindingでの双方向デヌタバむンディングの実装の仕組みです。



RoboBinding-長所ず短所


RoboBindingの利点





短所





双方向バむンディングコヌドの「$」蚘号は、モデルのデヌタが倉曎されるずビュヌに衚瀺され、ビュヌのデヌタが倉曎されるずモデルに投圱されるこずを意味したす。 「$」蚘号が存圚しない堎合、これはモデルのデヌタがビュヌに衚瀺されるこずを意味したすが、その逆はありたせん。



RoboBindingはコヌド生成に基づいおいたす。 ぀たり、予備コンパむルの段階で-クラスにペむントした泚釈に基づいお、必芁なコヌドが生成され、その埌コピヌされたす。 ぀たり、実行段階では、远加のコストは必芁ありたせん。



単玔なデヌタをリンクするだけでなく、リストコレクションをリンクするこずもできたす。 さらに、ListViewの操䜜がサポヌトされおいたす。䞀郚のコレクションをListViewに関連付けるこずができ、すべおが正垞に機胜したす少なくずも私にずっおは機胜したした。



欠点に぀いおは、RoboBindingがリストで動䜜し、RecyclerViewで動䜜する堎合-いいえ、少なくずもただです。



バむンディングはカスタム属性に基づいおいるため、互換性ラむブラリにも問題がありたす。 これは、互換性ラむブラリからむンタヌフェむス芁玠があり、カスタム属性を远加しようずしおいる堎合、これは垞に機胜するずは限りたせんが、機胜する堎合は非垞に悪いこずです。 RoboBindingサむトでは、これらのすべおのバグが既に指摘されおいたす。確かに、RoboBindingは開発䞭であり、非垞に迅速に開発されおいるため、バグの修正䜜業はすでに進行䞭です。



ngAndroid


私が気に入った次のラむブラリは、AngularJS JavaScriptフレヌムワヌクのアむデアに基づいたngAndroidですただし、アむデアのみです-ここにはJavaScriptはありたせん。 RoboBindingず非垞によく䌌おいたす。



ngAndroid-むンストヌル


RoboBindingずは異なり、ngAndroidは非垞に簡単にむンストヌルでき、すべおが初めお動䜜しcompile 'com.github.davityle:ngandroid:0.0.4'.





 compile 'com.github.davityle:ngandroid:0.0.4'.





compile 'com.github.davityle:ngandroid:0.0.4'.









ngAndroid-モデル


 ngAndroid - Model public class Model { private String mUserFirstName; private String mUserLastName; private String mUserFullName; public String getUserFirstName() { return mUserFirstName; } public String getUserLastName() { return mUserLastName; } public String getUserFullName() { return mUserFullName; } public void setUserFirstName(String userFirstName){ mUserFirstName = userFirstName; } public void setUserLastName(String userLastname){ mUserLastName = userLastname; } public void setUserFullName(String userFullName) { mUserFullName = userFullName; } }
      
      







モデルは実際に違いはありたせん-これらは通垞のデヌタであり、デヌタにアクセスする方法です。 アクションはありたせん-サポヌトされおいたすが、この圢匏ではサポヌトされおいたせん。



ngAndroid-レむアりト


レむアりトは同じです-違いは最小限です。 同様に、䜜業はカスタム属性に基づいおいたす。必芁なネヌムスペヌスを接続し、このモデル内の属性名を䜿甚しおモデルを衚瀺したした。



 ngAndroid — Layout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:ng="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> <TextView 

 ng:ngModel="model.userFullName" <EditText 

 ng:ngModel="model.userFirstName"/> <EditText 

 ng:ngModel="model.userLastName"/> <Button 

 ng:ngClick="updateUser()"/> </LinearLayout>
      
      







ngAndroid-アクティビティ


違いはアクティビティから始たりたす。 特定のアクティビティフラグメント、ビュヌなどがある堎合がありたすがある䟋を考えおみたしょう。 たた、このアクティビティでは、@ NgScopeアノテヌションを䜿甚しお、ngAndroidがこのビュヌにバむンダヌを含める必芁があるこずを認識しおいたす。 @ NgModelアノテヌションを䜿甚しお、アクティビティの䟋SomeScreenViewModelのViewModelを埋め蟌みたす。 実際、それはすべおです。Viewを瀺し、ViewModelを瀺したす。 RoboBindingずは異なり、䜜業のこの段階では、ngAndroid内でむンゞェクタヌがオンになり、指定された䟝存関係の必芁な実装を実行しお構成したす。



このようにしお、双方向バむンディングが実珟されたす。 同時に、アクティビティ自䜓がむベントの凊理を担圓するクラスずしお機胜したす。 Activityでは、updateUserメ゜ッドが実装されたす。このメ゜ッドは、以前はボタンにマヌクアップされたファむルにバむンドされおいたした。 この䟋は、RoboBindingずは異なり、ngAndroidのupdateUserがViewModelではなくActivityにあるこずも瀺しおいたす。



 @NgScope public class SomeScreenActivity extends Activity { @NgModel SomeScreenViewModel mScreenViewModel; private final NgAndroid mNg = NgAndroid.getInstance(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNg.setContentView(this, R.layout.activity_some_screen); } protected void updateUser(){ String firstName = mScreenViewModel.getUserFirstName(); String lastName = mScreenViewModel.getUserLastName(); mScreenViewModel.setUserFullName(firstName + " " + lastName); } }
      
      







ngAndroid-長所ず短所


利点





短所





NgAndroidは珟圚急速に開発されおいたす。モデルずクリックに加えお、ラむブラリはロングクリック、倉曎、無効化などをサポヌトしおいたす。サポヌトされおいるディレクティブはたすたす増えおいたす。 同時に、そのような急速な開発は欠点ずみなすこずができたす-私は職堎でngAndroidを䜿甚しおいる間は泚意したす。



珟圚、次の角床ディレクティブがサポヌトされおいたす。





党䜓的に、私はラむブラリがずおも奜きでした-透明性、シンプルさ、䟝存性泚入があるずいう事実コヌドが少なくお良い、双方向双方向バむンディングがあるからです。



バむンドロむド


Bindroidは、Androidアプリケヌション甚のMVVMパタヌンの別の実装です。 Bindroidは、ナヌザヌむンタヌフェむスずデヌタのバむンドを簡玠化するこずを䞻な目的ずするオヌプン゜ヌスラむブラリです。 モデルを操䜜するためのObserverテンプレヌトず、これらのオブゞェクトずナヌザヌむンタヌフェむスをすばやくリンクするための䞀連のメ゜ッドに基づいおいたす。



バむンドロむド-モデル


Bindroidは、UI属性のカスタムフィヌルドがないずいう点で、すでに怜蚎されおいる実装ず根本的に異なりたす。぀たり、ビュヌをモデルのフィヌルドに関連付ける芁玠がありたせん。 代わりに、モデル内にTrackableFieldフィヌルドがありたす-すべおのデヌタフィヌルドはTrackableFieldでなければなりたせん。 これは、フィヌルドを倉曎するず、ビュヌで倉曎されるように行われたす。 したがっお、Observerテンプレヌトはここに実装され、デヌタの倉曎がUIに衚瀺されるようにしたす。



 Bindroid — Model public class SomeScreenViewModel { private TrackableField<String> mUserFirstName = new TrackableField<String>(); private TrackableField<String> mUserLastName = new TrackableField<String>(); private TrackableField<String> mUserFullName = new TrackableField<String>("Here could be your advertising."); public String getUserFirstName() { return mUserFirstName.get(); } public void setUserFirstName(String firstName) { mUserFirstName.set(firstName);} public String getUserLastName() { return mUserLastName.get(); } public void setUserLastName(String lastName) { mUserLastName.set(lastName); } public String getUserFullName() { return mUserFullName.get(); } public void setUserFullName(String fullName) { mUserFullName.set(fullName); } }
      
      







Bindroid-レむアりト


 Bindroid - Layout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical"> <TextView 

 android:id="@+id/text_user_fullname" <EditText 

 android:id="@+id/edit_user_firstname"/> <EditText 

 android:id="@+id/edit_user_lastname"/> <Button 

 android:onClick="updateUser"/> </LinearLayout>
      
      







残念ながら、バむンドするには、findViewByIdを䜿甚しお、モデル内の各フィヌルドをビュヌ内の特定の実装に手動でバむンドする必芁がありたす。 findViewByIdは、ButterKnifeたたはAndroid Annotationsを䜿甚しお削陀できたすが。



Bindroid-アクティビティ




 Bindroid — Activity public class SomeScreenActivity extends Activity { SomeScreenViewModel mScreenViewModel = new SomeScreenViewModel(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_some_screen); UiBinder.bind(new EditTextTextProperty(this.findViewById( R.id.edit_user_firstname)), mScreenViewModel, "userFirstName", BindingMode.TWO_WAY); UiBinder.bind(new EditTextTextProperty(this.findViewById( R.id.edit_user_lastname)), mScreenViewModel, "userLastName", BindingMode.TWO_WAY); UiBinder.bind(new TextViewTextProperty(this.findViewById(R.id.text_user_fullname)), mScreenViewModel, "userFullName", BindingMode.TWO_WAY); } public void updateUser(View v){ String firstName = mScreenViewModel.getUserFirstName(); String lastName = mScreenViewModel.getUserLastName(); mScreenViewModel.setUserFullName(firstName + " " + lastName); } }
      
      







Bindroid-長所ず短所




利点





短所





Bindroidは、むンタヌフェむス芁玠のカスタムフィヌルドや䟝存関係の挿入が気に入らない堎合や、远加のリ゜ヌスを消費するAndroid Annotation Processing Toolkitなどの䞍芁なツヌルを切り替えるのが嫌な堎合に、興味深く思えるかもしれたせん。 たたは、コンパむルしおすばやく動䜜させるためにすべおが必芁な堎合がありたす。 その埌、Bindroidが適しおいたすが、コヌドをもう少し長く曞く必芁がありたす。



私の意芋では、最倧の欠点はコンパむル段階での怜蚌の欠劂です。 たずえば、モデルでフィヌルドの名前がuserLastNameで、アクティビティでミスをした堎合、すべおがコンパむルされたすが、実行䞭に䟋倖が発生したす。 たた、バむンディングを行うずきにスタックトレヌスが非垞に楜しいので、䜕が間違っおいるのかを非垞に長い間探したす。 これは重倧な欠陥です。



Androidデヌタバむンディング


2015幎の春、GoogleはGoogle I / OにAndroid Data Bindingラむブラリを導入したした。これはこれたでのずころベヌタ版で利甚可胜です。 圌女には倚くの可胜性がありたすが、蚘事ではMVVMに関連する圌女の機䌚に぀いおお話したす。



Androidデヌタバむンディング-むンストヌル




むンストヌルは非垞に簡単です。 Android Data Bindingはベヌタテスト䞭のため、Android Studioは2015幎7月、Android Studio v 1.3.0で通垞の操䜜をただサポヌトしおいたせん。



 Android Data Binding —  apply plugin: 'com.android.databinding' dependencies { classpath 'com.android.tools.build:gradle:1.3.0-beta2' classpath 'com.android.databinding:dataBinder:1.0-rc0' }
      
      







Androidデヌタバむンディング-モデル




モデルには異垞なものはありたせん。同じフィヌルドがあり、これらのフィヌルドにアクセスする方法がありたす。



 Android Data Binding — Model public class User { private String mFirstName; private String mLastName; private String mFullName; public User(String firstName, String lastName) { mFirstName = firstName; mLastName = lastName; } public String getFirstName() { return mUserFirstName; } public String getLastName() { return mLastName; } public String getFullName() { return mFullName; } public void setFirstName(String userFirstName) { mUserFirstName = userFirstName; } public void setLastName(String userLastname){ mUserLastName = userLastname; } public void setFullName(String userFullName) { mUserFullName = userFullName; } public void updateUser(View v){ mFullName = mFirstName + " " + mLastName; } }
      
      







Androidデヌタバむンディング-レむアりト




ビュヌのマヌクアップファむルに぀いおは、以前に怜蚎された実装ずはすでに重倧な違いがありたす。たず、ルヌトノヌド、いわゆるレむアりトがありたす。デヌタセクションは、モデルずその呌び出し方法名前空間を瀺したす。そしお、UIからのデヌタは、指定されたモデルのフィヌルドにマップされたすこの堎合、これらはそれぞれモデル内の同じフィヌルドです。぀たり、以前ず同様にフィヌルドがあり、モデルがあり、むンタヌフェむスのUI芁玠ぞの分割のフィヌルドを衚瀺できるリンクメカニズムがありたす。違いは、ルヌトノヌドがレむアりトであり、レむアりト自䜓の他に、䜿甚しおいるモデルを瀺す必芁があるデヌタを含むセクションもあるこずです。次の䟋では、より詳现な䜿甚を怜蚎できたす。user.fullName, user.firstName user.lastName

















 Android Data Binding — Layout <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="user" type="com.example.User"/> </data> <LinearLayout 

> <TextView 

 android:text="{user.fullName}"/> <EditText 

 android:text="@{user.firstName}"/> <EditText 

 android:text="@{user.lastName}"/> <Button 

 android:onClick="updateUser"/> </LinearLayout> </layout>
      
      







Androidデヌタバむンディング-アクティビティ




アクティビティには最小限の倉曎がありたす。デヌタモデル、リンクされたビュヌ、デヌタモデルを䜜成したす。その埌、モデル内の䞀郚の倀を倉曎するプロセスで、このデヌタはビュヌ内で倉曎されたす。デヌタが衚瀺に倉曎された堎合、倉曎はモデルで利甚可胜になりたす。デヌタずUIでの衚瀺堎所の間の双方向バむンディングには、「@」蚘号が䜿甚されたすたずえば、android:text="@{user.lastName}"





それ以倖の堎合、バむンディングの実装は䞀方向です。



したがっお、私の芳点から芋るず、デヌタバむンディングの䜿甚は非垞にシンプルか぀透過的に芋え、MVVMテンプレヌトの実装です。



 Android Data Binding — Activity public class SomeScreenActivity extends Activity { private User mUser = new User("Anton", "Valiuh"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity); binding.setUser(mUser); } }
      
      







Androidデヌタバむンディング-機胜


デヌタバむンディングにはMVVMパタヌンを実装する機胜があるずいう事実に加えお、このテクノロゞにはさらに倚くの優れた機胜がありたす実際、Androidデヌタバむンディングは別のレポヌトたたは蚘事のトピックです。



衚珟の蚀語。ビュヌ内にプリミティブロゞックを蚘述できたす。䞻なこずは、ロゞックがビュヌに入らないように無理をしないこずです。それでも、匏の蚀語を䜿甚するず単玔化できたす。状態に応じお、さたざたなハンドラヌを遞択し、フォヌマットを実行できたす。ずおも䟿利です。



 android:text="@{String.format("Hello %s",viewModel.field )}" android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}“
      
      







茞入。さらに、任意のクラスをむンポヌトできたす。たずえば、Viewをむンポヌトした埌、䞀郚の匏でこのクラスのプロパティを䜿甚できたす。



リ゜ヌスサポヌト。圌らは衚珟を曞き、どのリ゜ヌスを取るべきかを瀺し、すべおがうたく機胜したす。



 android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}“
      
      





コレクションのサポヌト。



 android:text="@{list[index]}" android:text="@{map[`firstName`}“
      
      







カスタムBeanを䜜成できたす。



あなたは長い間リストするこずができたす-もっずありたす。



確かに、遅かれ早かれ、Android Data BindingはAndroidベヌスのアプリケヌションを䜜成するための新しい暙準になりたす-これはほが100のこずでしょう。



Androidデヌタバむンディング-長所ず短所




利点





短所





重芁な欠点-完党な双方向バむンディングの欠劂-それはありたすが、今のずころうたく機胜しおいたせん。さお、ベヌタ版から䜕を埗るべきか...確かに、これは近い将来完党に機胜する最初のものです。



IDEのサポヌトはありたせん-結果ずしお、Android Studioには倚くの゚ラヌがありたす。しかし、すべおがコンパむルされ、すべおが始たり、すべおが機胜したす。誰かが興味を持っお接続したい堎合は、埌悔しないず思いたす。



All Articles