【问题标题】: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我正在尝试访问导航抽屉,以便当我单击应用栏的左上角时,我可以访问新活动中的设置
【发布时间】:2020-06-21 21:17:48
【问题描述】:

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

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>

【问题讨论】:

  • 能否提供navigation_graph xml文件?
  • navigation_graph.xml 文件位于drawer_menu.xml 的底部,为mobile_navigation.xml。这就是你想要的吗?

标签: java android navigation-drawer drawerlayout android-navigationview


【解决方案1】:

只需将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 处理对设置项的点击。

关于DrawerLayoutcheck the doc

注意:使用 NavigationUI 时,顶部应用栏助手会随着当前目的地的变化而自动在抽屉图标和向上图标之间转换。您不需要使用ActionBarDrawerToggle

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

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

【讨论】:

  • 哇,这很奏效,但现在导航抽屉打开并拒绝关闭。底部导航也有效。我该怎么做?
【解决方案2】:

您可以将&lt;activity&gt; 目的地添加到导航图中以启动另一个活动:

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

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

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

【讨论】:

    【解决方案3】:

    您的 Setting 活动不是 NavigationGraph 的一部分(即不是片段,而是单独的活动)。

    当你点击抽屉汉堡并选择设置时,它不会进入设置,因为你没有在 NavigationViewOnNavigationItemSelectedListener 上启动意图

    解决这个问题:

    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);
    

    【讨论】:

    • 我做了您推荐的更改。当我按下设置时,它不会打开新的活动。当我按下设置时它只是关闭菜单。
    • @ReinaldoGift 会在您从抽屉中点击“设置”时向您显示“设置”吗?
    • 不,它没有
    • 它说它无法解析该方法。 navView 用于底部导航视图,而 navigationView 用于导航视图。
    【解决方案4】:

    在菜单项中添加 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)
        }
    

    【讨论】:

      猜你喜欢
      • 2018-11-13
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多