导航抽屉:如何在启动时设置所选项目?

Navigation drawer: How do I set the selected item at startup?

我的代码运行完美:每次单击导航抽屉中的项目时,该项目都会被 selected。

当然,我想使用默认片段(主页)启动应用程序,但导航抽屉没有 selected 项。我如何以编程方式 select 该项目?

public class BaseApp extends AppCompatActivity {

    //Defining Variables
    protected String LOGTAG = "LOGDEBUG";
    protected Toolbar toolbar;
    protected NavigationView navigationView;
    protected DrawerLayout drawerLayout;

    private DateManager db = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.base_layout);

        navigationView = (NavigationView) findViewById(R.id.navigation_view);


        // set the home/dashboard at startup

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame, new DashboardFragment());
        fragmentTransaction.commit();

        setNavDrawer();
    }

    private void setNavDrawer(){

        // Initializing Toolbar and setting it as the actionbar
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //Initializing NavigationView

        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            // This method will trigger on item Click of navigation menu
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {


                //Checking if the item is in checked state or not, if not make it in checked state

                // I THINK THAT I NEED EDIT HERE...

                if (menuItem.isChecked()) menuItem.setChecked(false);
                else menuItem.setChecked(true);

                //Closing drawer on item click
                drawerLayout.closeDrawers();


                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()) {    

                    //Replacing the main content with ContentFragment 

                    case R.id.home:

                        DashboardFragment dashboardFragment = new DashboardFragment();
                        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame, dashboardFragment,"DASHBOARD_FRAGMENT");
                        fragmentTransaction.commit();
                        return true;
[...]

我想我需要在这里编辑:

if (menuItem.isChecked()) menuItem.setChecked(false);
                    else menuItem.setChecked(true);

或者在 onCreate 应用程序启动时使用 FragmentTransaction。

感谢您的支持。

使用下面的代码:

navigationView.getMenu().getItem(0).setChecked(true);

调用后调用此方法setNavDrawer();

getItem(int index)方法得到MenuItem然后你可以在那个MenuItem上调用setChecked(true);,你剩下要做的就是找出哪个元素索引默认有没有,用那个索引替换0。

您可以通过调用select(突出显示)项目

onNavigationItemSelected(navigationView.getMenu().getItem(0));

这里有一个参考 link: http://thegeekyland.blogspot.com/2015/11/navigation-drawer-how-set-selected-item.html

编辑 不适用于 nexus 4,支持库修订版 24.0.0。我推荐使用

navigationView.setCheckedItem(R.id.nav_item);

下面由@kingston 回答。

您也可以拨打:

navigationView.setCheckedItem(id);

此方法是在 API 23.0.0

中引入的

例子

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

    <group
        android:id="@+id/group"
        android:checkableBehavior="single">
        <item
            android:id="@+id/menu_nav_home"
            android:icon="@drawable/ic_home_black_24dp"
            android:title="@string/menu_nav_home" />
    </group>
</menu>

注:android:checkableBehavior="single"

另见 this

首先为所选项目创建颜色。这里 很好的例子。它可以帮助您更改图标的颜色。要更改所有选定项目的背景,请在 values\style.xml 文件中添加此

  <item name="selectableItemBackground">@drawable/selectable_item_background</item>

其中 selectable_item_background 应在 drawable/selectable_item_background 中声明。xml

  <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/accent_translucent"
      android:state_pressed="true" />
    <item android:drawable="@android:color/transparent" />
   </selector>

可以在 style.xml

中声明颜色的位置
 <color name="accent_translucent">#80FFEB3B</color>

之后

   // The main navigation menu with user-specific actions
        mainNavigationMenu_ = (NavigationView) findViewById(R.id.main_drawer);
        mainNavigationMenu_.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                mainNavigationMenu_.getMenu().findItem(itemId).setChecked(true);
                return true;
            }
        });

如你所见,我用过这个 mainNavigationMenu_.getMenu().findItem(itemId).setChecked(true); 设置所选项目。 这里navigationView

 <android.support.design.widget.NavigationView
        android:id="@+id/main_drawer"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/header_main_navigation_menu"
        app:itemIconTint="@color/state_list"
        app:itemTextColor="@color/primary"
        app:menu="@menu/main_menu_drawer"/>

对我来说这两种方法都不起作用:

  • navigationView.getMenu().getItem(0).setChecked(true);
  • navigationView.setCheckedItem(id);

试试这个,对我有用。

onNavigationItemSelected(navigationView.getMenu().findItem(R.id.nav_profile));

出于某种原因,最好使用 ID 查找 MenuItem。

drawer.getMenu().findItem(R.id.action_something).setChecked(true);

示例 (NavigationView.OnNavigationItemSelectedListener):

private void setFirstItemNavigationView() {
        navigationView.setCheckedItem(R.id.custom_id);
        navigationView.getMenu().performIdentifierAction(R.id.custom_id, 0);
}

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

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    FragmentManager fragmentManager = getFragmentManager();

    switch (item.getItemId()) {
        case R.id.custom_id:
            Fragment frag = new CustomFragment();

            // update the main content by replacing fragments
            fragmentManager.beginTransaction()
                    .replace(R.id.viewholder_container, frag)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .addToBackStack(null)
                    .commit();
            break;
    }

感谢

Google "oh so great" 支持库总是有问题。如果您想在不降级支持库版本的情况下检查项目,只需在设置检查状态之前设置可检查。

MenuItem item = drawer.getMenu().findItem(R.id.action_something);
item.setCheckable(true);
item.setChecked(true);

如果您在菜单 xml 文件

中设置为可检查,它也可能有效

以下代码只会生成菜单项 selected:

navigationView.setCheckedItem(id);

到select并打开菜单项,在上面一行之后添加以下代码。

onNavigationItemSelected(navigationView.getMenu().getItem(0));

您可以使用以下 1-liner 突出显示和 select 项目:

navigationView.getMenu().performIdentifierAction(R.id.posts, 0);

来源:

API23提供了如下方法:

navigationView.setCheckedItem(R.id.nav_item_id);

但是,由于某些原因,此功能并未导致导航项后面的代码变为 运行。该方法肯定会突出显示导航抽屉中的项目,或者 'checks' 它,但它似乎不会调用 OnNavigationItemSelectedListener 如果您的启动屏幕取决于导航,则会导致启动时出现空白屏幕抽屉 select 离子。手动调用监听器是可以的,但是看起来很hacky:

if (savedInstanceState == null) this.onNavigationItemSelected(navigationView.getMenu().getItem(0));

以上代码假定:

  1. 您已实施 NavigationView.OnNavigationItemSelectedListener 在你的 activity
  2. 您已经打过电话:
    navigationView.setNavigationItemSelectedListener(this);
  3. 您想要 select 的项目位于位置 0

这是我的解决方案,非常简单。

这是我的 menu.xml 文件:

<group
    android:id="@+id/grp1"
    android:checkableBehavior="single">
    <item
        android:id="@+id/nav_all_deals"
        android:checked="true"
        android:icon="@drawable/ic_all_deals"
        android:title="@string/all_deals" />
    <item
        android:id="@+id/nav_news_and_events"
        android:icon="@drawable/ic_news"
        android:title="@string/news_and_events" />
    <item
        android:id="@+id/nav_histories"
        android:icon="@drawable/ic_histories"
        android:title="@string/histories" />
</group>

上面的菜单将突出显示第一个菜单项。下面一行会做一些事情(例如:显示第一个片段等)。注意:写在 'configure your drawer code'

之后
onNavigationItemSelected(mNavigationView.getMenu().getItem(0));

为此您必须调用 2 个函数:

首先: 用于执行您在 onNavigationItemSelected 侦听器中实现的命令:

onNavigationItemSelected(navigationView.getMenu().getItem(R.id.nav_camera));

第二个:用于将导航抽屉菜单项的状态更改为选中(或选中):

navigationView.setCheckedItem(R.id.nav_camera);

我调用了这两个函数并且对我有用。

下面的代码用于在菜单中选择第一项突出显示所选的第一项

onNavigationItemSelected(mNavigationView.getMenu().getItem(0).setChecked(true));

为导航抽屉的个别项目制作选择器

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/darkBlue" android:state_pressed="true"/>
    <item android:drawable="@color/darkBlue" android:state_checked="true"/>
    <item android:drawable="@color/textBlue" />
</selector>

对 NavigationView 进行一些更改

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:itemBackground="@drawable/drawer_item"
        android:background="@color/textBlue"
        app:itemIconTint="@color/white"
        app:itemTextColor="@color/white"
        app:menu="@menu/activity_main_drawer"
        />

最简单的方法是 select 从 xml 如下,

<menu>
   <group android:checkableBehavior="single">
         <item
              android:checked="true"
              android:id="@+id/nav_home"
              android:icon="@drawable/nav_home"
              android:title="@string/main_screen_title_home" />

注意行 android:checked="true"

在你的activity(抽屉后面):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar,
               R.string.navigation_drawer_open,
               R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    navigationView.setCheckedItem(R.id.nav_portfolio);
    onNavigationItemSelected(navigationView.getMenu().getItem(0));
}

@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    Fragment fragment = null;

    if (id == R.id.nav_test1) {
        fragment = new Test1Fragment();
        displaySelectedFragment(fragment);
    } else if (id == R.id.nav_test2) {
        fragment = new Test2Fragment();
        displaySelectedFragment(fragment);
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

在您的菜单中:

<group android:checkableBehavior="single">

    <item
        android:id="@+id/nav_test1"
        android:title="@string/test1" />

    <item
        android:id="@+id/nav_test2"
        android:title="@string/test2" />

  </group>

所以第一个菜单是 highlightshow 作为默认菜单。

当使用 BottomNavigationView 时,其他答案如 navigationView.getMenu().getItem(0).setChecked(true);navigationView.setCheckedItem(id); 无法调用 setSelectedItemId 有效:

    BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation_view);

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            // TODO: 10-Aug-19 your code here 
        }
    });

    bottomNavigationView.setSelectedItemId(R.id.myitem);

你可以做到, nav_view.getMenu().findItem(R.id.menutem).setChecked(true)

bottomNavigationView.setSelectedItemId(R.id.menuItem);

以上对我有用,但我把它放在 onResume() 方法中。放在里面 onNavigationItemSelected(@NonNull MenuItem item) 在活动之间来回切换时给我带来了问题

   private BottomNavigationView bottomNavigationView;
    
     @Override
        public void onResume(){
            super.onResume();
            bottomNavigationView.setSelectedItemId(R.id.menuItem);
    
     } 
    package com.example.projectdesign;
    import androidx.annotation.NonNull;
    import androidx.appcompat.app.ActionBarDrawerToggle;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.view.GravityCompat;
    import androidx.drawerlayout.widget.DrawerLayout;
    import androidx.fragment.app.Fragment;
         import android.annotation.SuppressLint;
      import android.app.Activity;
     import android.content.Intent;
     import android.os.Bundle;
     import android.view.MenuItem;
    import android.widget.Toast;

    import com.google.android.material.navigation.NavigationView;

    public class MenuDrawer extends AppCompatActivity implements 
    NavigationView.OnNavigationItemSelectedListener{
    public DrawerLayout drawerLayout;
    public ActionBarDrawerToggle actionBarDrawerToggle;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu_drawer);

        drawerLayout = findViewById(R.id.my_drwaer_layout);
        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, 
      R.string.nav_open, R.string.nav_close);
        drawerLayout.addDrawerListener(actionBarDrawerToggle);
        actionBarDrawerToggle.syncState();
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        NavigationView navigationView = findViewById(R.id. nav_view ) ;
        navigationView.setNavigationItemSelectedListener( this ) ;
    }
    @SuppressLint("ResourceType")
    @SuppressWarnings ( "StatementWithEmptyBody" )
     @Override
    public boolean onNavigationItemSelected (MenuItem item){
        int id=item.getItemId();
        switch (id){
            case R.id.nav_account:
                Intent intent= new Intent(MenuDrawer.this, UsingBackKey.class);
                startActivity(intent);
                break;
            case R.id.women:
     
     
    getSupportFragmentManager().beginTransaction().replace(R.id.my_drwaer_layout,new 
    Fragment2()).commit();
                break;
            case R.id.men:
                Toast.makeText(getApplicationContext(),"Soon", 
   Toast.LENGTH_SHORT).show();
                break;
            case R.id.kids:
              Toast.makeText(getApplicationContext(),"Welcome to Kids", 
      Toast.LENGTH_SHORT).show();
                break;
        }
        drawerLayout.closeDrawer(GravityCompat.START);
        return super.onContextItemSelected(item);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {


        if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        return super.onOptionsItemSelected(item);

    }

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