web-dev-qa-db-ja.com

Androidナビゲーションアーキテクチャコンポーネント-ナビゲーションドロワーアイコン

現在、Android Architecture ComponentのNavigationを使用していますが、Navigation Drawer。出発地ではハンバーガーメニューが表示されますが、他のFragmentsは上矢印を表示しています。私はnavigation_graph間違っています。

ここには、ナビゲーションドロワーが表示され、ホームと設定の2つの項目が表示されています。これらのフラグメントのいずれかで、ハンバーガーアイコンが表示されます。

nav drawer

ただし、設定フラグメントに移動すると、上矢印が表示されます。

toolbar

navigation.graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    app:startDestination="@id/nav_home">

    <!-- Start at HomeFragment -->
    <fragment
        Android:id="@+id/nav_home"
        Android:name=".HomeFragment"
        Android:label="@string/home">

        <!-- Navigate to the Search -->
        <action
            Android:id="@+id/action_nav_home_to_nav_search"
            app:destination="@id/nav_search" />
    </fragment>


    <fragment
        Android:id="@+id/nav_settings"
        Android:name=".SettingsFragment"
        Android:label="@string/settings">

        <!-- Navigate to the Search -->
        <action
            Android:id="@+id/action_nav_settings_to_nav_search"
            app:destination="@id/nav_search" />
    </fragment>



    <fragment
        Android:id="@+id/nav_search"
        Android:name=".SearchFragment"
        Android:label="@string/search" />

</navigation>

HomeFragmentSettingsFragmentが何らかの形で関連しているように感じますが、それを定義する方法がわかりません。

main_drawer.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <group Android:checkableBehavior="single">
        <item
            Android:id="@id/nav_home"
            Android:icon="@drawable/ic_home_white_24dp"
            Android:title="@string/home" />

        <item
            Android:id="@id/nav_settings"
            Android:icon="@drawable/ic_settings_white_24dp"
            Android:title="@string/settings" />
    </group>
</menu>

主な活動

そして、MainActivity内で、このように設定しました。 setupActionBarWithNavControllerを呼び出しましたが、実際にナビゲーションドロワーを自分でセットアップし、onNavigationItemSelectedを処理する必要もあります。

private fun setupNavigation() {
    navController = findNavController(R.id.mainNavigationFragment)
    setupActionBarWithNavController(this, navController, drawer_layout)

    val toggle = ActionBarDrawerToggle(
                this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()

    nav_view.setNavigationItemSelectedListener(this)
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    val current = navController.currentDestination.id
    if (item.itemId != current) {
        navController.navigate(item.itemId)
    }

    drawer_layout.closeDrawers()
    return true
}

build.gradle

// Navigation
implementation 'Android.Arch.navigation:navigation-fragment-ktx:1.0.0-alpha04'
implementation 'Android.Arch.navigation:navigation-ui-ktx:1.0.0-alpha04'

ありがとう。

14
Advice-Dog

新しいアルファ版(1.0.0-alpha07があります)では、topLevelDestinationIdsコンストラクターを呼び出すときにAppBarConfigurationを定義する可能性が追加されました。

NavControllerを次のように設定します

    val navController = findNavController(R.id.nav_Host_fragment)
    val config = AppBarConfiguration(
        setOf(
            R.id.fistTopFragment,
            R.id.secondTopFragment,
            ...
        ),
        dr.drawerLayout
    )
    tb.setupWithNavController(navController, config)

ここで、drはMaterialDrawer、tbはもちろんツールバーです。

少なくともActionBarDrawerToggleについては、Gmailのように動作しますが、バックスタックは保持されます。 MaterialDrawerでアイテムの選択を自分で処理しなければならないので、包括的popToを含むグローバルナビゲーションアクションとナビゲーショングラフのルートフラグメントを使用してバックスタックアクションを減らし、「ようこそ画面」​​のようなものを使用します。

別の方法は、onBackPressedのカスタム処理です。最初にアクティビティレイアウトでホストフラグメントからapp:defaultNavHost="true"を削除する必要があります。このようなもの

override fun onBackPressed() {
    val navController = findNavController(R.id.nav_Host_fragment)
    if (navController.currentDestination == null
        || navController.currentDestination!!.id in setOf(
            R.id.fistTopFragment,
            R.id.secondTopFragment,
            ...
        )
    ) {
        super.onBackPressed()
    } else {
        navController.navigateUp()
    }
}

コードについては申し訳ありませんが、私はまだKotlinを学んでいるので、おそらくもっと良い方法があります。

6
Almighty

ナビゲーションコンポーネントの機能 であると思います。

また、非ルートの宛先にいる場合はアクションバーに[上へ]ボタンが表示され、ルートの宛先にある場合はドロワーアイコンが表示され、それらの間が自動的にアニメーション化されます。

必要に応じて、 setupWithNavController(NavigationView、NavController) を使用して、ツールバーを自分で処理してみてください。

3
ferini

この問題の簡単な例を作成しました。解決策は全能の答えとほぼ同じです。 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)
}
1
iSaul

必要に応じて、 NavController.OnNavigatedListener を使用し、以下のコードを使用してタイトルを設定できます。

@Override
public void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {
    mActivityBinding.toolbar.setTitle(destination.getLabel());
}

ナビゲーショングラフにラベルを設定してください。

1
Roshni Kyada

BottomNavigationViewに関連付けられたタブフラグメントに表示される戻る矢印は、意図した動作です。ただし、有名なアプリ(Instagram、下部のタブがあるYoutube)でも「そのまま」使用されているのを見たことはありません。たとえば、Youtubeアプリの別の下部タブに移動して、デバイスの戻るオプションをクリックすると、アプリを終了せずに前のタブフラグメントに移動することに気付くでしょう。そのため、bottomnavigationviewタブのフラグメントは、ここではルート宛先ではありません。

あなたが前進するときに遭遇するかもしれない追加の重要な問題に気付かせたい:

ただし、動作をカスタマイズするために使用できるフックがいくつかあります。

  1. onBackPressed-開いている場合に引き出しのレイアウトを閉じる

    _override fun onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
          drawerLayout.closeDrawer(GravityCompat.START)
        } else {
          super.onBackPressed()
        }
     }
    _
  2. navController.addOnNavigatedListener(..)を追加し、リスナー内でHomeAsUpIndicatorアイコンをカスタマイズします

  3. onOptionsItemSelectedをオーバーライドして、ID _Android.R.id.home_ actionのメニューをカスタマイズします

  4. カスタムフラグメントナビゲーターを設定して、フラグメントの処理方法をカスタマイズします(置換または表示/非表示)

    _navHostFragment = supportFragmentManager
            .findFragmentById(R.id.my_nav_Host_fragment) as NavHostFragment? ?: return
    val customNavigator = CustomFragmentNavigator(navHostFragment.requireContext(),
            navHostFragment.childFragmentManager, navHostFragment.id)
    navHostFragment.navController.navigatorProvider.addNavigator(customNavigator)
    
    val inflater = navHostFragment.navController.navInflater
    val graph = inflater.inflate(R.navigation.main_nav_graph)
    navHostFragment.navController.graph = graph
    _

ナビゲーションArchコンポーネントはまだアルファ版ですので、賢く使用してください。

1
random

メニュー項目は次のようになっているはずです。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item
            Android:id="@id/nav_home"
            Android:icon="@drawable/ic_home_white_24dp"
            Android:title="@string/home" />

        <item
            Android:id="@id/nav_settings"
            Android:icon="@drawable/ic_settings_white_24dp"
            Android:title="@string/settings" />

</menu>

お役に立てれば

ハッピーコーディング...

0
Abdul Aziz

私はここの感情に完全に同意しますが、それは図書館の一部です

setupActionBarWithNavController

NavControllerで使用するために、AppCompatActivity.getSupportActionBar()によって返されるActionBarを設定します。

このメソッドを呼び出すことにより、宛先が変更されたときにアクションバーのタイトルが自動的に更新されます(有効なラベルがある場合)。

ナビゲーショングラフの開始目的地は、唯一の最上位の目的地と見なされます。ナビゲーショングラフの開始先で、指定されたDrawerLayoutがnullでない場合、ActionBarはドロワーアイコンを表示します。他のすべての宛先では、ActionBarはUpボタンを表示します。 navigateUp(NavController、DrawerLayout)を呼び出して、Upボタンを処理します。

私にとってこれは壊れており、望ましい結果ではないので、私はまだナビゲーションビューでそれを使用しています

    navController = Navigation.findNavController(this, R.id.nav_Host);
    NavigationUI.setupWithNavController(navigationView,navController);

そして、タイトルと私がこのように変更したい他のものを更新するリスナーを持っています

   navController.addOnNavigatedListener((controller, destination) -> {
        setToolbarColour(R.color.primary);
        switch (destination.getId()){
            case R.id.dashBoard :
                setToolbarColour(Android.R.color.transparent);
                break;
            case R.id.requests :
                toolbar.setTitle(getString(R.string.request));
                break;

        }
    });

次に、これらのフラグメントごとに新しいナビゲーショングラフを作成しますが、うまくいきませんが、意図した結果が得られます

0
martinseal1987