web-dev-qa-db-ja.com

Androidダイアログからのjetpackナビゲーションコンポーネントの結果

これまでのところ、ナビゲーションコンポーネントのみを使用してダイアログに戻ったり、戻ったりすることに成功しています。問題は、ダイアログでいくつかのことを行い、ダイアログが呼び出されたフラグメントに結果を返す必要があることです。

1つの方法は、共有ビューモデルを使用することです。しかし、そのためには、.of(activity)を使用する必要があります。これにより、不要になった場合でも、アプリがメモリを占有するシングルトンが残ります。

別の方法は、show(fragmentManager、id)メソッドをオーバーライドし、フラグメントマネージャーへのアクセスを取得し、そこから、前のフラグメントへのアクセスを取得することで、targetfragmentとして設定できます。コールバックインターフェイスを実装する前にtargetFragmentアプローチを使用したので、ダイアログでtargetFragmentに結果を通知できます。しかし、ナビゲーションコンポーネントアプローチでは、それはハックに感じられ、ある時点で機能しなくなる可能性があります。

他に何かやりたいことはありますか?多分最初のアプローチで問題を修正する方法はありますか?

7
SMGhost

Navigation 2.3.0-alpha02以降では、NavBackStackEntryはSavedStateHandleへのアクセスを提供します。 SavedStateHandleは、データの保存と取得に使用できるKey-Valueマップです。これらの値は、構成変更を含むプロセスの終了後も存続し、同じオブジェクトを通じて引き続き使用できます。指定されたSavedStateHandleを使用すると、宛先間でデータにアクセスして渡すことができます。これは、スタックからポップされた後、宛先からデータを取得するメカニズムとして特に役立ちます。

Destination BからDestination Aにデータを戻すには、まずSavedStateHandleで結果をリッスンするようにDestination Aを設定します。これを行うには、getCurrentBackStackEntry()APIを使用してNavBackStackEntryを取得し、SavedStateHandleによって提供されるLiveDataを観察します。

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val navController = findNavController();
// We use a String here, but any type that can be put in a Bundle is supported
navController.currentBackStackEntry?.savedStateHandle?.getLiveData("key")?.observe(
    viewLifecycleOwner) { result ->
    // Do something with the result.
}

}

宛先Bでは、getPreviousBackStackEntry()APIを使用して、宛先AのSavedStateHandleに結果を設定する必要があります。

navController.previousBackStackEntry?.savedStateHandle?.set("key", result)
1
Hamed safari