web-dev-qa-db-ja.com

ナビゲーションアーキテクチャコンポーネント-引数データをstartDestinationに渡す

アクティビティBを開始して、いくつかのインテントデータを渡すアクティビティAがあります。アクティビティB新しいナビゲーションアーキテクチャコンポーネントからナビゲーショングラフをホストします。そのインテントデータをstartDestinationフラグメントに引数として渡す方法を教えてください。

29

OK、GoogleチームのIan Lakeのおかげでその問題の解決策を見つけました。いくつかのインテントデータでアクティビティBを開始するアクティビティAがあり、startDestinationでそのデータを取得したいとしましょう。安全な引数を使用する場合、ここで2つのオプションがあります。

StartFragmentArgs.fromBundle(requireActivity().intent?.extras)

インテントから引数を読み取ります。安全な引数を使用しない場合は、フラグメントrequireActivity().intent?.extrasメソッドの代わりに使用できるバンドルを返す自己使用getArguments()バンドルからデータを抽出できます。それは私がそれを試してみて、すべてがうまく機能するということです。

8

TLDR:グラフを手動で膨張させ、キー/値をdefaultArgsに追加し、navControllerにグラフを設定する必要があります。

ステップ1

ドキュメントでは、Activityのレイアウトの<fragment>タグにグラフを設定するよう指示されています。何かのようなもの:

<fragment
    Android:id="@+id/navFragment"
    Android:name="androidx.navigation.fragment.NavHostFragment"
    app:graph="@navigation/nav_whatever"
    app:defaultNavHost="true"
    />

graph=を設定している行を削除します。

ステップ2

NavHostFragmentを表示するアクティビティで、グラフを次のように展開します。

val navHostFragment = navFragment as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.nav_whatever)

ここで、navFragmentは、上記のようにXMLでフラグメントに指定したIDです。

ステップ3 [重要!]

startDestinationフラグメントに渡す引数を保持するバンドルを作成し、グラフのデフォルト引数に追加します。

val bundle = Bundle()
// ...add keys and values
graph.addDefaultArguments(bundle)

ステップ4

ホストのnavControllerにグラフを設定します:

navHostFragment.navController.graph = graph
21
Elliot Schrock

1.0.0-alpha07で修正されていました。 詳細を参照

ソリューションはElliot Schrockの答えに似ていますが、公式のAPIでラップします。

NavHostFragmentまたはgraphを手動で膨張させる必要があります

つかいます

NavHostFragment.create(R.navigation.graph, args)

または

navController.setGraph(R.navigation.graph, args)

argsは、宛先を開始するために渡すデータです。

11
HvSimon

これは1.0.0リリースで再び変わったと思います。また、Googleは公式文書にこの情報を非常によく隠しています。または、少なくとも見つけるのに苦労しましたが、Migrate to the Navigation componentガイドで見つけました。開始先に引数を渡す方法は次のとおりです。

https://developer.Android.com/guide/navigation/navigation-migrate#pass_activity_destination_args_to_a_start_destination_fragment

要するに

  1. ナビゲーショングラフをプログラムで設定する必要があります。
findNavController(R.id.main_content)
                .setGraph(R.navigation.product_detail_graph, intent.extras)
  1. NavHostFragment XML宣言でグラフを設定しないでください。
  2. 受信機側からエキストラを読む:
val args by navArgs<ProductDetailsArgs>()  
val productId = args.productId

更新:Googleは、最初のナビゲーションターゲットに引数を渡すための公式ドキュメントが実際に欠落していると述べています。ナビゲーションコンポーネントのドキュメントの一部として、これがすぐに追加されることを願っています。

5
Johan Paul

この回答を書いている時点では、Navigation 2.2.0-alpha01を使用しています

ホストアクティビティから引数としてデータを開始先に直接渡す場合は、以下に示すように、ホストアクティビティのonCreate()メソッド内でホストのナビゲーショングラフを手動で設定する必要があります。

NavControllerを入手:

val navController by lazy { findNavController(R.id.<your_nav_Host_id>) }

次に、ホストアクティビティのonCreate()

val bundle = Bundle()
bundle.putString("some_argument", "some_value")
navController.setGraph(R.navigation.<you_nav_graph_xml>, bundle)

または、startDestinationにインテントエクストラ全体をそのまま渡す場合:

navController.setGraph(R.navigation.<you_nav_graph_xml>, intent.extras)

intent.extrasBundleのみを返すため

SetGraph()メソッドを使用してnavGraphを設定する場合、NavHostFragment定義でapp:NavGraph属性を設定しないようにしてください。設定すると、ナビゲーショングラフが2回膨らんで設定されるためです。

StartDestinationフラグメントでこれらの引数を読み取り中:

Safe Args Plugin (これは非常にお勧めです)を使用している場合、フラグメント内で:

private val args by navArgs<DummyFragmentArgs>()

Safe Argsプラグインは、フラグメント名にArgsを追加することによりArgsクラスを生成します。たとえば、フラグメントがDummyFragmentという名前の場合、Safe ArgsはDummyFragmentArgsというクラスを生成します

navArgs<>Android KTX で定義されている拡張関数です

Android KTXを使用していない場合、次のようなargsオブジェクトを取得できます。

val args = DummyFragmentArgs.fromBundle(arguments!!)

引数オブジェクトを取得したら、引数を簡単に取得できます。

args.someArgument

引数として"some_argument"を渡し、Safe Argsを使用してsomeArgumentとして読み取っていることに注意してください。

Safe Argsを使用していない場合(ただし、使用しない理由はありません)、次のように引数にアクセスできます。

arguments?.getString("some_argument")

これはすべて、ナビゲーションコンポーネントへの移行のドキュメントに記載されています: https://developer.Android.com/guide/navigation/navigation-migrate#pass_activity_destination_args_to_a_start_destination_fragment

0
Praveen Singh

だから、まだこれに苦しんでいる人々のために。 Safe-Argsを使用せずにこれを行う別の方法と、@ Elliot's Answerを使用する手順を見つけました。

アクティビティAからアクティビティBで引数を受け取り、アクティビティBに次のようにNavコントローラを初期化するフラグメントstartDestinationがあるとします。

navController = Navigation.findNavController(this, R.id.detailFragment);

nav Controllerから、次のようにXMLで設定したグラフにアクセスでき、defaultArgumentsで引数を設定できます。

navController.getGraph().addDefaultArguments(extras);

注:グラフxmlに既に存在する場合、これはキーの値も更新します

これで、フラグメント内で、次のようにNavHostFragmentからデフォルト引数を見つける必要があります。

Bundle defaultArguments = NavHostFragment.findNavController(this).getGraph().getDefaultArguments();

そこに値があります。 @Elliotがなぜそれが重要であると考えるのかわかりませんが、それが道であるべきですか?

PDATE alpha09: addDefault引数は、このバージョンではサポートされなくなりました。NavArgumentを使用する必要があります

0
Dr. aNdRO