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


229

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

当然,我想使用默认片段(主页)启动应用程序,但是Navigation Drawer没有选择该项。如何以编程方式选择该项目?

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。

感谢您的支持。


是否有任何答案触发onNavigationItemSelected针对所选ID的操作?
Prabs

Answers:


478

使用以下代码:

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

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

getItem(int index)方法获取MenuItem之后,您可以调用setChecked(true);on,MenuItem剩下要做的就是找出默认值包含哪个元素索引,然后用该索引替换0。

您可以通过调用选择(突出显示)该项目

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

这是参考链接: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在下面回答。


65
Android支持库v23已添加setCheckedItem (int id)
马库斯·鲁比

1
@MarkusRubey即使设置了setCheckedItem后,我也无法突出显示所选项目。你能说出可能的原因吗?
Dexto

3
不适合我!当 导航菜单抽屉中的其他选项调用方法onNavigationItemSelected时,称为“已检查”的初始项始终保持其状态。当我使用'navigationView.setCheckedItem(id);' 工作完美!之后,它必须调用方法“ navigationView.getMenu()performIdentifierAction(R.id.nav_market,0);”。执行所需项目的选择。
GFPF

3
出于某种原因,上述提到的方法都不对我有用。但是,这样做navigationView.post(new Runnable() { navigationView.setCheckedItem(...) })-可行。
dimsuz

1
您可能正在尝试从与主线程不同的线程中更改已检查的项目:)
Arlind

105

您也可以致电:

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"

另请参见


1
即使设置了setCheckedItem之后,我也无法突出显示所选项目。你能说出可能的原因吗?
Dexto

3
@DeepeshDoshi请确保您的行为可检查。
Jared Burrows

1
应该选择navigationView.setCheckedItem(R.id.menu_nav_home)来选择主菜单
贾加

对于单个商品,只需添加android:checkable="true"其他内容,否则不会自行检查。
sud007

另外,请确保您不要从中调用此方法,navItemSelecteListener因为在此方法返回后选中了该项。
mallaudin

47

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

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

试试这个,对我有用。

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


2
感谢您的提示。上面的方法实际上可以,但是问题有所不同:如果使用它们,则不会调用onNavigationItemSelected,仅会检查菜单项。因此,我们需要同时调用这两种方法。
user1209216

2
onNavigationItemSelected(navView.getMenu()。getItem(0)); 或onNavigationItemSelected(navView.getMenu()。getItem(R.id.nav_profile)); 两者都对我有用,用getitem代替finditem。
严苛的Dalwadi,

30

示例(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;
    }

ks


2
我喜欢这是一种方法。但是,通常不鼓励仅使用代码的答案。我将对您的答案进行修改,以稍微解释一下代码,例如您为什么使用performIdentifierAction以及其中发生了什么onNavigationItemSelected。对您来说,这似乎很简单,但是新开发人员可能无法理解您的代码。
AdamMc331

@ McAdam331当然,请放心,今天已经过去了一半,没有时间详细写信。
GFPF

25

谷歌的支持库总是存在问题。如果要在不降低支持库版本的情况下检查项目,只需在设置检查状态之前将检查设置为可检查即可。

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

如果您在菜单xml文件中设置了checkable,它也可能会起作用



9

API 23提供以下方法:

navigationView.setCheckedItem(R.id.nav_item_id);

但是,由于某种原因,此功能并未导致导航项目后面的代码运行。该方法肯定会突出显示导航抽屉中的项目,或对其进行“检查”,但是,OnNavigationItemSelectedListener如果您的启动屏幕取决于导航抽屉的选择,它似乎不会在启动时导致空白屏幕。可以手动调用侦听器,但这似乎很麻烦:

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

上面的代码假定:

  1. 您已NavigationView.OnNavigationItemSelectedListener在活动中实施
  2. 您已经致电:
    navigationView.setNavigationItemSelectedListener(this);
  3. 您要选择的项目位于位置0

6

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

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

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

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

navigationView.setCheckedItem(R.id.nav_camera);

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


5

以下代码只会使菜单项处于选中状态:

navigationView.setCheckedItem(id);

要选择并打开菜单项,请在上一行之后添加以下代码。

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


4

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

这是我的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>

菜单上方将突出显示第一个菜单项。在下面的行中将执行某些操作(例如:显示第一个片段等)。注意:在“配置您的抽屉代码”之后写

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

4

最简单的方法是从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"


1
我认为最好的答案是,原因使用默认的Android提供的逻辑。如果菜单使用布局而不是由适配器xml文件而不是适配器生成,则最好投票为更好。
安德里斯

1
这是最好的答案
Ganesh Chowdhary Sadanala

2

首先为所选项目创建颜色。这里https://stackoverflow.com/a/30594875/1462969很好的例子。它可以帮助您更改图标的颜色。要更改所有选定项目的背景,请在您的values \ style.xml文件中添加以下内容

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

应该在drawable / selectable_item_background.xml中声明selectable_item_background的位置

  <?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"/>

我喜欢这种方法,目前我在自己的项目中使用它。将@color/state_list代码包含在答案中可能会有所帮助。出于好奇,您从哪儿得到了在变量名末尾加下划线的命名约定?我从未见过这种方法。
2015年

我想也许您想要menuItem.getItemId()而不是itemId
Craig Russell

2

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

0

选择导航抽屉的单个项目

<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"
        />

0

在您的活动中(抽屉后面):

@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>

因此第一个菜单是突出显示显示为默认菜单。


0

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

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

您能否告诉我onNavigationItemSelected的访问方式和位置?请提供完整的代码示例。
kgkahn


-1

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

drawer.getMenu().findItem(R.id.action_something).setChecked(true);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.