导航抽屉:如何在启动时设置所选项目?
Posted
技术标签:
【中文标题】导航抽屉:如何在启动时设置所选项目?【英文标题】: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
中。
感谢您的支持。
【问题讨论】:
是否有任何答案会触发所选 ID 的onNavigationItemSelected
操作?
@Prabs 是的,***.com/questions/31233279/…
【参考方案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 支持库 v23setCheckedItem (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://***.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));
以上代码假设:
-
您已实施
NavigationView.OnNavigationItemSelectedListener
在你的活动中
您已经致电:navigationView.setNavigationItemSelectedListener(this);
您要选择的项目位于位置 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>
所以第一个菜单是 highlight 和 show 作为默认菜单。
【讨论】:
【参考方案13】:首先为所选项目创建颜色。这里https://***.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;
);
如你所见,我使用了这个 mainNavigationMenu_.getMenu().findItem(itemId).setChecked(true); 设置所选项目。 这里是导航视图
<android.support.design.widget.NavigationView
android:id="@+id/main_drawer"
android:layout_
android:layout_
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_
android:layout_
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);
【讨论】:
以上是关于导航抽屉:如何在启动时设置所选项目?的主要内容,如果未能解决你的问题,请参考以下文章