27

Androidのドキュメントでは、アクティビティからホストされたフラグメントに通信するために、フラグメントはコールバックインターフェイスを定義し、ホストアクティビティがそれを実装することを要求できることを示唆しています。基本的なパターンにはonAttach、フラグメントに実装し、アクティビティをコールバックインターフェイスにキャストすることが含まれます。http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivityを参照してください。

これは、フラグメントに初期化データを提供し、ナビゲーションコールバックをリッスンする例です。

public class HostActivity extends Activity implements FragmentHost {
  @Override
  UiModel getUiModel() {
    return mUiModel;
  }
  @Override
  FragmentNavListener getNavListener() {
    return mNavListener;
  }
...
}

public class HostedFragment extends Fragment {
  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof FragmentHost) {
      FragmentHost host = (FragmentHost) activity;
      setUiModel(host.getUiModel());
      setNavListener(host.getFragmentNavListener());
    }
  }
  ...
}

onAttachFragmentこれをホストアクティビティで使用してフラグメントを明示的に初期化することと比較してください。

public class HostActivity extends Activity {
  @Override
  public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);
    if (fragment instanceof HostedFragment) {
      HostedFragment hostedFragment = ((HostFragment) fragment);
      hostedFragment.setUiModel(mUiModel);
      hostedFragment.setNavListener(mNavListener);
    }
  }
  ...
}

私には、最初のパターンにはいくつかの欠点があるように思われます。

  1. これらのアクティビティはすべて必要なインターフェイスを実装する必要があるため、さまざまなアクティビティからフラグメントを使用するのが難しくなります。特定のフラグメントインスタンスがホストアクティビティによって完全に構成されている必要はないが、すべての潜在的なホストアクティビティがホストインターフェイスを実装する必要がある場合を想像できます。
  2. 使用されているパターンに慣れていない人にとっては、コードを理解するのが少し難しくなります。初期化コードはフラグメントを作成するのと同じクラスに存在するため、onFragmentAttachedでフラグメントを初期化する方が簡単なようです。
  3. onAttach(new Activity()を呼び出すだけでなく、FragmentHostを実装する必要があるため、Robolectricなどのライブラリを使用した単体テストは難しくなります。

コミュニケーションを断片化する活動をしたことがある人にとって、どのパターンが好ましいと思いますか、そしてその理由は何ですか?onAttachFragmentホストアクティビティから使用することには欠点がありますか?

4

3 に答える 3

6

テストに関して個人的に話すことはできませんが、フラグメント/アクティビティ コールバック インターフェイス通信の代替手段があります。

たとえば、イベント バスを使用して、フラグメントとアクティビティを切り離すことができます。優れたイベント バスは次の場所にあります。

Otto - イベント バス バイ スクエア

これは、Square の非常に才能のあるエンジニアによって積極的に開発されています。Android サポート ライブラリにパッケージ化されている LocalBroadcastManager を使用することもできます。

LocalBroadcastManager

square の Eric Burke がプレゼンテーションを行っており、両方について言及しています。

Android アプリの構造

于 2012-10-15T23:08:08.437 に答える
2

Fragment.onAttach(...)前回のプロジェクトでこのパターンを使用しました。2 つの利点があります。

  1. ホスティング アクティビティが必要なインターフェイスを実装していることを早期に確認し、そうでない場合は例外をスローできます。
  2. フラグメントがデタッチされた後、ホスティング コンテキストの参照を保持するリスクが少なくなります。

UiModel2. を利用するには、コード サンプルのようにとへの参照を保存NavListenerしないでください。代わりに、これらのインスタンスとやり取りしたいときはいつでも((FragmentHost) getActivity).getNavListener().onNav(this)、または代わりにのようなコードを使用する必要があります((FragmentHost) getActivity).onNav(this)onDetach(...)一定のキャストを避けたい場合は、中立的なアプローチとしてnullに設定したフィールドにフラグメントホストを保存できます。

フラグメントを作成するアクティビティからフラグメントを初期化する方が直感的に思えることに同意します。

そうは言っても、現在のプロジェクトではフラグメントを完全にスキップします。次の投稿は、前回の投稿から学んだ教訓をよく反映しています: https://corner.squareup.com/2014/10/advocating-against-android-fragments.html

于 2015-06-20T21:04:31.117 に答える