web-dev-qa-db-ja.com

複数のフラグメントがあるアクティビティのMVP

2つのフラグメントを含むアクティビティがあります。

アクティビティ(MainActivity)は、オープン天気apiからデータを取得します。このためにMVPを実装しました。Modelには、APIからのすべての応答オブジェクトが含まれます
ViewActivityです
Presenterには、MainPresenterMainPresenterImplMainViewGetDataInteractor、およびGetDataInteractorImplが含まれます。

そのため、アクティビティはWebサービスからデータを取得します。両方のフラグメントは、アクティビティで取得したデータのデータを表示します。

この状況でMVPを使用するベストプラクティスは何ですか?インターフェイス/コールバックを介してフラグメント<->アクティビティ間でデータを渡す方法を知っています。私の質問は、MVPを実装するとこの動作が変わるのですか?

38
DJ-DOO

アクティビティ/フラグメントは、MVPモデルの単なるビューと見なす必要があります。これは、データを表示するだけでユーザーとの対話を受信する必要があることを意味します。インターフェイス/コールバックを介してアクティビティとフラグメントを通信しても構いません。

ただし、APIサービスを呼び出すことはアクティビティ/フラグメントの責任ではありません。

プレゼンターは、APIサービスを呼び出す必要があります。

そのため、プレゼンターはloadXXXのようなメソッドを公開する必要があります。内部的にはサービスを呼び出します。応答が受信されると、プレゼンターはサービスの結果で_view.showXXX_を呼び出す必要があります。アクティビティ/フラグメントは、このloadXXXメソッドを呼び出し、showXXXを実装する必要があります。

通常、プレゼンターはアクティビティ/フラグメントに作成または挿入されます。アクティビティ/フラグメントは、プレゼンターによって公開されるインターフェースを実装する必要があり、プレゼンターは、コールバックできるように、このインターフェースの弱い参照を保持します。

ユーザーが画面上のボタン(たとえば、ボタン上のonClick)と対話すると、アクティビティ/フラグメントはプレゼンターの対応するメソッドを呼び出します。 presenter.loadUserDetails()プレゼンターは、ビューを読み込み中として表示するよう指示します。 view.showAsLoading()それは何かをしなければならないからです:多分何かを検証するか、APIサービスからデータをロードし、最終的にビューへの結果でコールバックします。 view.showUserDetails(userDetails)

MVPのさまざまな部分のコードの例を要約すると、次のとおりです。

アクティビティ/フラグメントは、MVPのビューのみを表します。

_public class MyActivity extends AppCompatActivity implements MyPresenter.View {
    private MyPresenter mPresenter;

    public onCreate() {
        ...
        mPresenter = new MyPresenter(this); // Or inject it and then set the view.
    }

    public void onClick(View v) {
        mPresenter.loadXXX(param1, param2);
    }

    // MyPresenter.View methods

    public void showAsLoading() {
        ...
    }

    public void showUserDetails(UserDetails userDetails) {
        ...
    }
}
_

モデル:

_public class UserDetails {
    ...
}
_

プレゼンター:

_public class MyPresenter {

    private WeakReference<MyPresenter.View> mWeakView;

    public MyPresenter(MyPresenter.View view) {
        mWeakView = new WeakReference(view);
    }

    public void loadXXX(String param1, String param2) {
        MyPresenter.View view = mWeakView.get();
        if (view != null) {
            view.showAsLoading();
            // Do stuff, e.g. make the Api call and finally call view.showUserDetails(userDetails);
        }
    }

    interface View {
        void showAsLoading();
        void showUserDetails(UserDetails userDetails);
    }

}
_
17
fernandospr