71

Last Google IO で、Google はいくつかの新しいアーキテクチャ コンポーネントのプレビューをリリースしました。そのうちの 1 つは ViewModel.

docs googleでは、このコンポーネントの可能な用途の 1 つを示しています。

アクティビティ内の 2 つ以上のフラグメントが互いに通信する必要があることはよくあります。両方のフラグメントがインターフェイスの説明を定義する必要があり、所有者アクティビティが 2 つをバインドする必要があるため、これは決して簡単なことではありません。さらに、両方のフラグメントは、他方のフラグメントがまだ作成されていない、または表示されていない場合を処理する必要があります。

この共通の問題点は、ViewModel オブジェクトを使用して対処できます。ユーザーがリストからアイテムを選択するフラグメントと、選択したアイテムの内容を表示する別のフラグメントがある、マスター/ディテール フラグメントの一般的なケースを想像してみてください。

これらのフラグメントは、アクティビティ スコープを使用して ViewModel を共有し、この通信を処理できます。

実装例を示します。

public class SharedViewModel extends ViewModel {
    private final SavedStateHandle state;

    public SharedViewModel(SavedStateHandle state) {
        this.state = state;
    }

    private final MutableLiveData<Item> selected = state.getLiveData("selected");

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}

public class MasterFragment extends Fragment {
    private SharedViewModel model;

    @Override
    protected void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(getActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {
    @Override
    protected void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(getActivity()).get(SharedViewModel.class);
        model.getSelected().observe(this, { item ->
           // update UI
        });
    }
}

アクティビティを介して通信するためにフラグメントに使用されるインターフェイスを必要としない可能性について、私は非常に興奮していました。

しかし、Google の例では、マスターから詳細フラグメントを呼び出す方法が正確に示されていません。

fragmentManager.replace(...) を呼び出すアクティビティによって実装されるインターフェイスを使用する必要がありますか、それとも新しいアーキテクチャを使用してそれを行う別の方法がありますか?

4

8 に答える 8

6

コンテナと見なされるアクティビティにアタッチするコールバックを使用する前。
そのコールバックは、2 つの Fragment の間の仲介者です。この以前のソリューションの悪い点は次のとおりです。

  • アクティビティはコールバックを実行する必要があります。これは、アクティビティの多くの作業を意味します。
  • 2 つの Fragment は緊密に結合されているため、後でロジックを更新または変更することは困難です。

新しい ViewModel (LiveData のサポート付き) を使用すると、洗練されたソリューションが得られます。これは、そのライフサイクルをアクティビティに関連付けることができる仲介者の役割を果たします。

  • 2 つの Fragment 間のロジックとデータが ViewModel に配置されるようになりました。
  • 2 つの Fragment は ViewModel からデータ/状態を取得するため、お互いを知る必要はありません。
  • さらに、LiveData の機能を使用すると、以前のコールバック方法ではなく、リアクティブなアプローチでマスター Fragment の変更に基づいて詳細 Fragment を変更できます。

アクティビティと関連するフラグメントの両方に密接に結合するコールバックを完全に取り除きます。Google の Code Lab
を使用 することを強くお勧めします。ステップ 5 で、これに関する良い例を見つけることができます。

于 2017-05-31T00:24:15.553 に答える