【问题标题】:Navigation drawer: How do I set the selected item at startup?导航抽屉:如何在启动时设置所选项目?
【发布时间】:2015-09-22 20:35:31
【问题描述】:

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

当然,我想使用默认片段(主页)启动应用程序,但 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);

或在应用启动时使用 FragmentTransaction 在onCreate 中。

感谢您的支持。

【问题讨论】:

标签: android navigation-drawer


【解决方案1】:

使用下面的代码:

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

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

getItem(int index) 方法得到MenuItem 然后你可以在那个MenuItem 上调用setChecked(true);,剩下要做的就是找出默认的元素索引,并将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 回答了。

【讨论】:

  • 添加了 Android 支持库 v23 setCheckedItem (int id)
  • @MarkusRubey 即使在设置 setCheckedItem 之后我也无法突出显示所选项目。你能说出可能的原因吗?
  • 不适合我!当导航菜单抽屉中的其他选项调用方法onNavigationItemSelected 时,称为“已检查”的初始项始终保持其状态。当我使用'navigationView.setCheckedItem(id);'工作完美!之后它必须调用方法'navigationView.getMenu () performIdentifierAction (R.id.nav_market, 0);'执行所需项目的选择。
  • 由于某种原因,上述两种方法都不适合我。但是做navigationView.post(new Runnable() { navigationView.setCheckedItem(...) }) - 工作。
  • 您可能正试图从与主线程不同的线程更改选中的项目 :)
【解决方案2】:

您也可以调用:

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

【讨论】:

  • 即使在设置 setCheckedItem 之后,我也无法突出显示所选项目。你能说出可能的原因吗?
  • @DeepeshDoshi 请确保您有可检查的行为。
  • navigationView.setCheckedItem(R.id.menu_nav_home) 应该选择主菜单
  • 对于单个项目只需添加android:checkable="true" 否则不会自行检查。
  • 另外,请确保不要从 navItemSelecteListener 调用此方法,因为此方法返回后选择了项目。
【解决方案3】:

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

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

试试这个,它对我有用。

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

【讨论】:

  • 感谢您的提示。以上方法其实没问题,但问题不同:如果你使用它们,onNavigationItemSelected 将不会被调用,只会检查菜单项。所以我们需要调用这两个方法。
  • onNavigationItemSelected(navView.getMenu().getItem(0));或 onNavigationItemSelected(navView.getMenu().getItem(R.id.nav_profile));两者都对我有用,getitem 而不是 finditem。
  • 但是如果onNavigationItemSelected返回true,为什么这个方法也不检查项目呢?
【解决方案4】:

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

Tks

【讨论】:

  • 这是一种方法,我喜欢。但是,通常不鼓励仅使用代码的答案。我会编辑您的答案以稍微解释一下代码,例如您为什么使用performIdentifierAction 以及onNavigationItemSelected 中发生了什么。对您来说,这似乎很简单,但新开发人员可能无法理解您的代码。
  • @McAdam331 当然随意,今天就到这里了一半,没时间再详细写了。
【解决方案5】:

Google 的“太棒了”支持库总是存在问题。如果您想在不降级支持库版本的情况下检查项目,只需在设置检查状态之前设置可检查。

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

如果您在菜单 xml 文件中设置 checkable 也可能有效

【讨论】:

    【解决方案6】:

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

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

    来源:https://stackoverflow.com/a/31044917/383761

    【讨论】:

      【解决方案7】:

      API 23 提供以下方法:

      navigationView.setCheckedItem(R.id.nav_item_id);
      

      但是,由于某种原因,此函数没有导致导航项后面的代码运行。该方法肯定会突出显示导航抽屉中的项目,或“检查”它,但如果您的启动屏幕取决于导航抽屉选择,它似乎不会调用OnNavigationItemSelectedListener 导致启动时出现空白屏幕。可以手动调用监听器,但看起来很hacky:

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

      以上代码假设:

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

      【讨论】:

        【解决方案8】:

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

        第一:用于执行你在onNavigationItemSelected监听器中实现的命令:

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

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

        navigationView.setCheckedItem(R.id.nav_camera);
        

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

        【讨论】:

          【解决方案9】:

          以下代码只会选择菜单项:

          navigationView.setCheckedItem(id);

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

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

          【讨论】:

            【解决方案10】:

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

            【讨论】:

            • 在我看来最好的答案,原因使用默认的 Android 提供的逻辑。如果菜单使用布局并且由适配器而不是菜单 xml 文件生成,则投票为最好的更好。
            • 这是最好的答案
            【解决方案11】:

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

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

            【讨论】:

              【解决方案12】:

              关于你的活动(在抽屉后面):

              @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 作为默认菜单。

              【讨论】:

                【解决方案13】:

                首先为所选项目创建颜色。这里https://stackoverflow.com/a/30594875/1462969 很好的例子。它可以帮助您更改图标的颜色。要更改所有选定项目的背景,请在您的 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;
                            }
                        });
                

                如你所见,我使用了这个 ma​​inNavigationMenu_.getMenu().findItem(itemId).setChecked(true); 设置所选项目。 这里是导航视图

                 <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 代码可能会有所帮助。出于好奇,您从哪里得到在变量名末尾添加下划线的命名约定?我从未见过这种方法。
                • 我想你可能想要menuItem.getItemId()而不是itemId
                【解决方案14】:

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

                【讨论】:

                  【解决方案15】:

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

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

                  【讨论】:

                  • 您能告诉我这个 onNavigationItemSelected 的访问方式和位置吗?请提供更完整的代码示例。
                  【解决方案16】:

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

                  【讨论】:

                    【解决方案17】:

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

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

                    【讨论】:

                      【解决方案18】:
                      bottomNavigationView.setSelectedItemId(R.id.menuItem);
                      

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

                         private BottomNavigationView bottomNavigationView;
                          
                           @Override
                              public void onResume(){
                                  super.onResume();
                                  bottomNavigationView.setSelectedItemId(R.id.menuItem);
                          
                           } 
                      

                      【讨论】:

                        【解决方案19】:

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

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

                        【讨论】:

                          猜你喜欢
                          • 2016-04-07
                          • 2016-10-12
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-07-27
                          • 2014-06-12
                          相关资源
                          最近更新 更多