web-dev-qa-db-ja.com

複数のトップレベルの目的地があるナビゲーショングラフ

私はAndroidアプリ(Kotlinにありますが、これは問題に関係ありません)を空き時間に実装しています。そして、Android jetpack and newライブラリ:ナビゲーションドロワーを持つ単一のアクティビティがあります sample sunflower app をたどろうとします。メインアクティビティで次の組み合わせを使用して、ナビゲーションドロワーの背後にあるロジックを有効にします。

appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
setSupportActionBar(findViewById(R.id.toolbar))
setupActionBarWithNavController(navController, appBarConfiguration)

このコードに関する注意:ナビゲーションドロワーでクリックすると自動的に正しいフラグメントに移動し、ドロワーを閉じて選択したままにします。コード。それは非常にきちんと動作します。これを理解している限り、ナビゲーションドロワーメニュー項目のIDは、ナビゲーショングラフ内のフラグメントのIDと一致している必要があります。

私が持っている問題:ナビゲーションドロワーを使用して、ナビゲーショングラフの開始フラグメント以外のフラグメントに移動すると、戻るボタンが表示されますハンバーガーアイテムの代わりに。ナビゲーションドロワーは、同じレベルのビュー間をナビゲートするためのものであり、互いにネストされていないため、ハンバーガーアイテムであると期待しています。フラグメントの要素(たとえば、リスト->詳細)をクリックしてフラグメントのサブフラグメントに移動する場合、ナビゲーションドロワーを使用して移動する場合ではなく、戻るボタンが必要です。

今、私はその問題をAppBarConfigurationビルダーにまでさかのぼり、ビルダーはnavgraph The NavGraph whose start destination should be considered the only top level destination.AppBarConfigurationをオーバーライドして、ナビゲーショングラフの開始目的地とは異なるトップレベルの目的地を返すことで、この問題をかなり簡単に修正できます。

しかし、私の質問は、なぜこの動作のデフォルトがあるのですか?バグですか?これを無効にすると、Googleの設計ガイドラインに違反しますか?ナビゲーションドロワーのすべての要素が期待どおりに同じレベルにあるとは限りませんか?私がしたい別の解決策がありますか?

9
findusl

AppBarConfigurationをオーバーライドする必要はありません。バージョンalpha7 AppBarConfigurationには、すべての最上位の宛先の一連のIDを持つコンストラクターがあります。

Set<Integer> topLevelDestinations = new HashSet<>();
topLevelDestinations.add(R.id.fragment1);
topLevelDestinations.add(R.id.fragment2);
appBarConfiguration = new AppBarConfiguration.Builder(topLevelDestinations)
                                             .setDrawerLayout(drawerLayout)
                                             .build();
NavigationUI.setupActionBarWithNavController(this, 
                                             this.navController,
                                             this.appBarConfiguration);

ナビゲーショングラフには、常にアプリケーションの単一のエントリポイントである単一の開始フラグメントのみが含まれるため、これはデフォルトではありません。

AppBarConfigurationでデフォルトの動作を編集しても、以前のようには動作しません。すべてのトップレベルフラグメントがバックスタックに配置されるため、戻るボタンはすべてのトップレベルフラグメントに移動します。バックスタックの最初の要素としてトップレベルのフラグメントをどのように作成できるかは不明です。

18
Elias DC

この問題の簡単な例を作成しました。 https://github.com/isaul32/Android-sunflower

最初にトップレベルの宛先のセットを作成します

val topLevelDestinations = setOf(R.id.garden_fragment,
        R.id.plant_list_fragment)
appBarConfiguration = AppBarConfiguration.Builder(topLevelDestinations)
        .setDrawerLayout(drawerLayout)
        .build()

そして、このようにonSupportNavigateUp関数をオーバーライドします

override fun onSupportNavigateUp(): Boolean {
    return NavigationUI.navigateUp(navController, appBarConfiguration)
}
4
iSaul

複数のトップレベルの宛先を持つツールバーとドロワーの正しい動作を取得するには、次のコードを使用できます。

val navController = Navigation.findNavController(this, R.id.nav_Host_fragment)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
val drawerLayout = findViewById<DrawerLayout>(R.id.drawer_layout)

/*
Create AppBarConfiguration with set of top level destinations and drawerLayout
Set contains ids of your navigation graph screens
*/
val appBarConfiguration = AppBarConfiguration(
    setOf(R.id.defaultFragment, R.id.firstFragment, R.id.secondFragment), 
    drawer_layout
)

//finally configure toolbar
toolbar.setupWithNavController(navController, appBarConfiguration)

このコードにより、すべての最上位の目的地にハンバーガーアイコンが表示され、さらに深く移動すると戻るボタンが表示されます。

続きを読む こちら

1
UrosKekovic