我正在尝试访问导航抽屉,这样当我点击应用栏的左上角时,我可以在新的 activity 中访问设置

I am trying to access navigation drawer so that when i click on the top left corner of app bar, I can access settings in a new activity

我正在尝试访问导航抽屉,这样当我单击应用栏的左上角时,我可以在新的 activity 中访问设置。现在,当我单击左上角然后单击设置时,我得到的是菜单缩回,没有其他任何反应。我也有一个底部导航栏。请帮忙。这是我目前所拥有的:

NavigationActivity.java

package com.tt.lateoclock;

import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.widget.Toolbar;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
import com.google.firebase.database.DatabaseReference;
import com.tt.lateoclock.Prevalent.Prevalent;
import com.tt.lateoclock.ui.findFood.FindFoodFragment;


import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;

import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.recyclerview.widget.RecyclerView;
import de.hdodenhof.circleimageview.CircleImageView;

public class NavigationActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, BottomNavigationView.OnNavigationItemSelectedListener {

    DrawerLayout drawer;
    NavigationView navigationView;
    Menu menu;

    private DatabaseReference merchantRef;
    RecyclerView recyclerView;
    RecyclerView.LayoutManager layoutManager;
    ActionBarDrawerToggle toggle;
    Intent settingsIntent;
    NavController navController;
    AppBarConfiguration appBarConfiguration;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_navigation);


        //merchantRef = FirebaseDatabase.getInstance().getReference().child("Merchants");


        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        toolbar.setTitle("Home");


        drawer = findViewById(R.id.container);
        toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);

        drawer.addDrawerListener(toggle);
        toggle.syncState();

        navigationView = findViewById(R.id.nav_view);

        BottomNavigationView navView = findViewById(R.id.bot_nav_view);

        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_find_food, R.id.navigation_favorites, R.id.navigation_map, R.id.navigation_receipts, R.id.navigation_settings)
                .build();
        navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
        NavigationUI.setupWithNavController(navView, navController);

        View headerView = navigationView.getHeaderView(0);
        TextView name = (TextView)headerView.findViewById(R.id.username);
        CircleImageView user_image = (CircleImageView)headerView.findViewById(R.id.user_image);

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                int id=menuItem.getItemId();
                Toast.makeText(getApplicationContext(), id, Toast.LENGTH_SHORT).show();
                //it's possible to do more actions on several items, if there is a large amount of items I prefer switch(){case} instead of if()
                if (id==R.id.navigation_settings){
                    Toast.makeText(getApplicationContext(), "Settings", Toast.LENGTH_SHORT).show();
                }
                //This is for maintaining the behavior of the Navigation view
                NavigationUI.onNavDestinationSelected(menuItem, navController);
                //This is for closing the drawer after acting on it
                drawer.closeDrawer(GravityCompat.START);
                return true;
            }
        });


        name.setText(Prevalent.currentUser.getName());
        
        navigationView.setNavigationItemSelectedListener(this);


    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController=Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }

    @Override
    public void onBackPressed()
    {
        if(drawer.isDrawerOpen(GravityCompat.START))
        {
            drawer.closeDrawer(GravityCompat.START);
        }
        else{
            super.onBackPressed();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.navigation_settings:
                settingsIntent = new Intent(this, SettingsActivity.class);
                startActivity(settingsIntent);


            default:
                return super.onOptionsItemSelected(item);
        }
    }


    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_find_food:
                getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new FindFoodFragment()).commit();
                break;
            case R.id.navigation_favorites:
                getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new com.tt.lateoclock.ui.favorites.FavoritesFragment()).commit();
                break;
            case R.id.navigation_receipts:
                getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, new com.tt.lateoclock.ui.receipts.ReceiptsFragment()).commit();
                break;

            case R.id.navigation_settings:
                Toast.makeText(this, "Settings selected", Toast.LENGTH_SHORT).show();
                Intent settingsIntent = new Intent(this, SettingsActivity.class);
                startActivity(settingsIntent);
                Toast.makeText(this, "Settings selected", Toast.LENGTH_SHORT).show();
                return true;
        }
        return true;
    }
}

activity_navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    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"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".NavigationActivity">

    <com.google.android.material.navigation.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:id="@+id/nav_view"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/drawer_menu"/>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <fragment
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_marginTop="?android:attr/actionBarSize"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/mobile_navigation" />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorPrimaryDark"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            />
        
<com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bot_nav_view"
            android:layout_width="match_parent"
            android:layout_height="196dp"
            android:layout_below="@id/nav_host_fragment"
            android:layout_marginTop="-100dp"
            android:layout_gravity="bottom"
            android:background="?android:attr/windowBackground"
            app:menu="@menu/bottom_nav_menu" >
        </com.google.android.material.bottomnavigation.BottomNavigationView>
    </RelativeLayout>

</androidx.drawerlayout.widget.DrawerLayout>

bottom_nav_menu.xml

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

    <item
        android:id="@+id/navigation_find_food"
        android:icon="@drawable/ic_local_dining_black_24dp"
        android:title="@string/title_find_food" />

    <item
        android:id="@+id/navigation_favorites"
        android:icon="@drawable/ic_favorite_black_24dp"
        android:title="@string/title_favorites" />

    <item
        android:id="@+id/navigation_map"
        android:icon="@drawable/ic_map_black_24dp"
        android:title="@string/title_map" />

    <item
        android:id="@+id/navigation_receipts"
        android:icon="@drawable/ic_receipt_black_24dp"
        android:title="@string/title_receipts" />

</menu>

drawer_menu.xml

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

        <item android:id="@+id/nav_message"
            android:title="Message"
            android:icon="@drawable/ic_message"/>

        <item android:id="@+id/nav_profile"
            android:title="Profile"
            android:icon="@drawable/ic_profile"/>

        <item android:id="@+id/navigation_settings"
            android:title="Settings"
            android:icon="@drawable/ic_settings_black_24dp"
            android:enabled="true"/>
</menu>

mobile_navigation.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"
    android:id="@+id/mobile_navigation"
    app:startDestination="@+id/navigation_find_food">

    <fragment
        android:id="@+id/navigation_find_food"
        android:name="com.tt.lateoclock.ui.findFood.FindFoodFragment"
        android:label="@string/title_find_food"
        tools:layout="@layout/fragment_find_food" />

    <fragment
        android:id="@+id/navigation_favorites"
        android:name="com.tt.lateoclock.ui.favorites.FavoritesFragment"
        android:label="@string/title_favorites"
        tools:layout="@layout/fragment_favorites" />

    <fragment
        android:id="@+id/navigation_map"
        android:name="com.tt.lateoclock.ui.map.MapFragment"
        android:label="@string/title_map"
        tools:layout="@layout/fragment_map" />

    <fragment
        android:id="@+id/navigation_receipts"
        android:name="com.tt.lateoclock.ui.receipts.ReceiptsFragment"
        android:label="@string/title_receipts"
        tools:layout="@layout/fragment_receipts" />

</navigation>

此处您的设置 activity 不是 NavigationGraph 的一部分(即不是片段,它是一个单独的 activity)。

当您点击抽屉汉堡并选择设置时,它不会进入设置,因为您没有在 NavigationView[=16] 的 OnNavigationItemSelectedListener 上启动 Intent =]

解决这个问题:

navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        int id=menuItem.getItemId();
        Toast.makeText(getApplicationContext(), id, Toast.LENGTH_SHORT).show();
        //it's possible to do more actions on several items, if there is a large amount of items I prefer switch(){case} instead of if()
        if (id==R.id.navigation_settings){
            Toast.makeText(getApplicationContext(), "Settings", Toast.LENGTH_SHORT).show();
            Intent settingsIntent = new Intent(NavigationActivity.this, SettingsActivity.class); // <<< Here is the change
            startActivity(settingsIntent); // <<< Here is the change
        }
        //This is for maintaining the behavior of the Navigation view
        NavigationUI.onNavDestinationSelected(menuItem, navController);
        //This is for closing the drawer after acting on it
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
});

更新

替换

navigationView.setNavigationItemSelectedListener(this);

navView.setNavigationItemSelectedListener(this);

只需将 activity_navigation.xml 更改为

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    ...>

    <RelativeLayout...>

    <com.google.android.material.navigation.NavigationView
        android:layout_gravity="start"
         .../>

</androidx.drawerlayout.widget.DrawerLayout>

此外,您还必须使用 navigationView.setNavigationItemSelectedListener 处理对设置项的点击。

关于 DrawerLayout check the doc:

Note: When using NavigationUI, the top app bar helpers automatically transition between the drawer icon and the Up icon as the current destination changes. You don't need to use ActionBarDrawerToggle.

在您的代码中删除有关 ActionBarDrawerToggle 的代码并使用:

AppBarConfiguration appBarConfiguration =
        new AppBarConfiguration.Builder(...........)
            .setDrawerLayout(drawerLayout)
            .build();

您可以将 <activity> 目的地添加到您的导航图中以开始另一个 activity:

<activity
    android:id="@+id/navigation_settings"
    android:name="com.your.package.SettingsActivity" />

然后,setupWithNavController() / onNavDestinationSelected() 的默认行为将为您启动 activity。您无需编写任何自定义代码或手动调用 setNavigationItemSelectedListener 即可获得此行为。

您还应该强烈考虑根据 onNavDestinationSelected() documentationmenuCategory="secondary" 添加到您的 navigation_settings 菜单项,以避免您当前的目的地从返回堆栈中弹出。

在菜单项中添加OnClick方法

<item
     android:id="@+id/nav_whats_app"
     android:icon="@drawable/ic_menu_settings"
     android:title="@string/menu_settings"
     android:onClick="onOpenSettings" />

然后像这样在activity中添加方法

//Kotlin Android
fun onOpenSettings(item: MenuItem) {
//... open settings here
}

Java代码

//Java Android
void onOpenSettings(MenuItem item) {
//... open settings here
}

要关闭任何导航抽屉,只需调用

val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
    if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
        drawerLayout.closeDrawer(GravityCompat.START)
    }