
投稿者:Anton Valyukh、シニアモバイルデベロッパー。
この記事では、Androidアプリケーションの開発時に非常に便利なMVVM(Model-View-ViewModel)設計パターンを使用する理論と実践について説明します。
MVP-モデルビュープレゼンター
手始めに、ちょっとした理論。 それはすべて、多くの人々がユーザーインターフェイスを備えたアプリケーションを作成するためにMVC(Model-View-Controller)テンプレートをどのように適合させるかを考えたという事実から始まりました。 そして2006年、「
GUIアーキテクチャ 」の仕事で
、 Martin Fowlerは後に「MVP」(「Model-View-Presenter」)として知られるようになったテンプレートを詳細に調査しました。
そのため、MVPはMVCから派生したデザインパターンであり、主にユーザーインターフェイスを構築するために設計されています。 MVPは、自動ユニットテストを容易にし、ロジックと表示の分離を改善するために使用されます。
このテンプレートには3つの要素があります。
- 表示する
- プレゼンター。
- モデル
すべての仕組みは次のとおりです。

- View要素は、ユーザーデータの表示とユーザーアクションのキャプチャを行います。 このすべてが彼がプレゼンターに送信します。
- PresenterはUIでユーザーアクションを処理し、モデルでのデータ変更を考慮して、この情報をビューに送信します。 プレゼンターは、ユーザーインターフェイスを操作するすべてのビジネスロジックを含む要素です。
- モデルには、アプリケーションの知識とデータドメインを表示するドメインモデルが含まれています。 モデルは、Presenterデータ変更情報を送信し、Presenterからメッセージを受信します。
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-同じフィールドを含みますが、サブジェクト領域にあります。
- 実際、モデル。
ビューのプロパティは、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の利点:
- 双方向(双方向)バインディング。
- コード生成;
- リストのサポート。
短所:
- AppCompatライブラリの問題。
- RecyclerViewのサポートはありません。
双方向バインディング:コードの「$」記号は、モデルのデータが変更されるとビューに表示され、ビューのデータが変更されるとモデルに投影されることを意味します。 「$」記号が存在しない場合、これはモデルのデータがビューに表示されることを意味しますが、その逆はありません。
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-長所と短所
利点:
- 双方向バインディング;
- プロジェクトは活発に開発中です。
短所:
- リスト/ RecyclerViewのサポートなし;
- リフレクションが使用されます(コード生成に切り替えることを約束します)。
- プロジェクトは活発に開発中であるため、非常に粗雑です。
NgAndroidは現在急速に開発されています。モデルとクリックに加えて、ライブラリはロングクリック、変更、無効化などをサポートしています。サポートされているディレクティブはますます増えています。 同時に、そのような急速な開発は欠点とみなすことができます-私は職場でngAndroidを使用している間は注意します。
現在、次の角度ディレクティブがサポートされています。
- ngmode
- NGClick
- NgLongClick
- Ngchange
- Ngdisabled
- NgInvisible
- ヌゴン
- Ngblur
- Ngfocus
全体的に、私はライブラリがとても好きでした-透明性、シンプルさ、依存性注入があるという事実(コードが少なくて良い)、双方向(双方向)バインディングがあるからです。
バインドロイド
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-長所と短所
利点:
- 双方向バインディング;
- AppCompatライブラリでの作業をサポートします。
短所:
- コード生成のサポートなし;
- コンパイル時にチェックインしません。
- リンクするにはコードが多すぎます。
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データバインディング-長所と短所
利点:- Googleの公式ライブラリ。
- コード生成;
- コンパイル時に確認します。
- 使いやすさと拡張性。
- 新しいAndroid標準。
短所:
- 双方向バインディングはサポートされていません(まだ)。
- IDEのサポートなし(まだ)。
- Android Studioの多くの誤ったエラー(ただし、すべてがコンパイルされて起動します)。
重要な欠点-完全な双方向バインディングの欠如-それはありますが、今のところうまく機能していません。さて、ベータ版から何を得るべきか...確かに、これは近い将来完全に機能する最初のものです。IDEのサポートはありません-結果として、Android Studioには多くのエラーがあります。しかし、すべてがコンパイルされ、すべてが始まり、すべてが機能します。誰かが興味を持って接続したい場合は、後悔しないと思います。