基本的に、次のナビゲーショングラフがあります。
スプラッシュ画面のように、戻るボタンを押したときにfragment 2
に戻らないようにするために、ナビゲーショングラフの開始点をfragment 1
に到達した直後に変更したい。
これは私のコードです:
navGraph = navController.getGraph();
navGraph.setStartDestination(R.id.fragment2);
navController.setGraph(navGraph);
しかし、明らかにそれは機能しておらず、戻るボタンを押すとfragment 1
に戻ります。
私は間違っていますか?他の解決策はありますか?
このようなナビゲーショングラフがある場合:
<fragment
Android:id="@+id/firstFragment"
Android:name="com.appname.package.FirstFragment" >
<action
Android:id="@+id/action_firstFragment_to_secondFragment"
app:destination="@id/secondFragment" />
</fragment>
<fragment
Android:id="@+id/secondFragment"
Android:name="com.appname.package.SecondFragment"/>
そして、2番目のフラグメントに移動してグラフのルートにし、次のNavOptions
を指定します。
NavOptions navOptions = new NavOptions.Builder()
.setPopUpTo(R.id.firstFragment, true)
.build();
そしてそれらをナビゲーションに使用します:
Navigation.findNavController(view).navigate(R.id.action_firstFragment_to_secondFragment, bundle, navOptions);
setPopUpTo(int destinationId, boolean inclusive)
-ナビゲートする前に特定の目的地にポップアップします。これにより、この宛先が見つかるまで、一致しないすべての宛先がバックスタックからポップされます。
destinationId
-ポップアップする宛先。すべての介在する宛先をクリアします。
inclusive
-指定された宛先もバックスタックからポップする場合はtrue。
<fragment
Android:id="@+id/firstFragment"
Android:name="com.appname.package.FirstFragment" >
<action
Android:id="@+id/action_firstFragment_to_secondFragment"
app:destination="@id/secondFragment"
app:popUpTo="@+id/firstFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
Android:id="@+id/secondFragment"
Android:name="com.appname.package.SecondFragment"/>
そして、あなたのコードで:
findNavController(fragment).navigate(
FirstFragmentDirections.actionFirstFragmentToSecondFragment())
廃止予定:アクションのclearTask
属性およびNavOptions
の関連APIは廃止されました。
ソース: https://developer.Android.com/jetpack/docs/release-notes
ルートフラグメントをfragment 2
に変更する場合(たとえば、fragment 2
の戻るボタンを押した後、アプリを終了します)、次の属性をaction
またはdestination
:
app:clearTask="true"
実際には次のように見えます:
<fragment
Android:id="@+id/firstFragment"
Android:name="com.appname.package.FirstFragment"
Android:label="fragment_first" >
<action
Android:id="@+id/action_firstFragment_to_secondFragment"
app:destination="@id/secondFragment"
app:clearTask="true" />
</fragment>
<fragment
Android:id="@+id/secondFragment"
Android:name="com.appname.package.SecondFragment"
Android:label="fragment_second"/>
アクションにapp:clearTask="true"
を追加しました。
今、fragment 1
からfragment 2
へのナビゲーションを実行するとき、次のコードを使用します。
Navigation.findNavController(view)
.navigate(R.id.action_firstFragment_to_secondFragment);
私はこれに対する解決策を見つけましたが、それはいです。これはアルファライブラリで期待されていることだと思いますが、これは非常に人気のあるナビゲーションパターンであるため、Googleがこれを簡素化/修正することを検討することを望みます。
Alexeyのソリューションは私にはうまくいきませんでした。私の問題は、使用して上矢印がアクションバーに表示されることでした:
NavigationUI.setupActionBarWithNavController(this, navController)
アレクセイが上記のように提案したように、新しい開始フラグメントには、まだ最初の開始フラグメントを指す矢印がありました。上矢印を押すと、アプリは再起動し、それ自体に移行します(新しい開始フラグメント)
私が望んでいたものに到達するために必要なコードは次のとおりです:
これを実現するコードを次に示します。私のアクティビティのonCreateで:
// Setup the toolbar
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(false)
// Configure the navigation
val navHost = nav_Host_fragment as NavHostFragment
graph = navHost.navController
.navInflater.inflate(R.navigation.nav_graph)
graph.startDestination = R.id.welcomeFragment
// This seems to be a magical command. Not sure why it's needed :(
navHost.navController.graph = graph
NavigationUI.setupActionBarWithNavController(this, navHost.navController)
また:
fun makeHomeStart(){
graph.startDestination = R.id.homeFragment
}
次に、Alexeyの提案によるフラグメント#1のonActivityCreatedで:
override fun onActivityCreated(savedInstanceState: Bundle?) {
...
// Check for user authentication
if(sharedViewModel.isUserAuthenticated()) {
(activity as MainActivity).makeHomeStart() //<---- THIS is the key
val navOptions = NavOptions.Builder()
.setPopUpTo(R.id.welcomeFragment, true)
.build()
navController.navigate(R.id.action_welcomeFragment_to_homeFragment,null,navOptions)
} else {
navController.navigate(R.id.action_welcomeFragment_to_loginFragment)
}
}
キーコードは次のとおりです:(activity as MainActivity).makeHomeStart()
これは、グラフのstartDestinationを変更するアクティビティでメソッドを実行するだけです。これを整理してインターフェイスに変えることはできましたが、Googleを待って、このプロセス全体が改善されることを願っています。メソッド 'setPopUpTo'の名前は私にはあまりよくないようで、グラフから切り取られるフラグメントに名前を付けるのは直感的ではありません。また、navOptionsでこれらの変更を行っているのも不思議です。 navOptionsは、それらが接続されているナビゲーションアクションにのみ関連すると思います。
そして、私はnavHost.navController.graph = graph
が何をするのかさえ知りませんが、それなしでは上矢印が戻ります。 :(
Navigation 1.0.0-alpha06を使用しています。