在Android BottomNavigationView中设置选定的项目

我正在使用支持库中的新的android.support.design.widget.BottomNavigationView 。 我怎样才能从代码中设置当前的select? 我意识到,旋转屏幕后,select被改回到第一项。 当然,如果有人能告诉我,如何在onPause函数中“保存” BottomNavigationView的当前状态以及如何在onResume恢复BottomNavigationView

谢谢!

Solutions Collecting From Web of "在Android BottomNavigationView中设置选定的项目"

从API 25.3.0开始,它引入了方法setSelectedItemId(int id) ,让您将项目标记为被选中,就好像它被点击了一样。

从文档:

设置选定的菜单项ID。 这与在物品上轻敲相同。

代码示例:

 BottomNavigationView bottomNavigationView; bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationView); bottomNavigationView.setSelectedItemId(R.id.my_menu_item_id); 

我不确定这是否是这个问题的完整答案,但我的问题非常相似 – 我不得不按backbutton,并将用户带到他以前的标签。 所以,也许我的解决scheme对于某人有用:

 private void updateNavigationBarState(int actionId){ Menu menu = bottomNavigationView.getMenu(); for (int i = 0, size = menu.size(); i < size; i++) { MenuItem item = menu.getItem(i); item.setChecked(item.getItemId() == actionId); } } 

请记住,如果用户按其他导航选项卡BottomNavigationView将不会清除当前选定的项目,所以你需要在你的onNavigationItemSelected处理导航动作后调用这个方法:

 @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.some_id_1: // process action break; case R.id.some_id_2: // process action break; ... default: return false; } updateNavigationBarState(item.getItemId()); return true; } 

关于实例状态的保存,我认为你可以使用导航视图的相同action id来find合适的解决scheme。

以编程方式点击您需要使用的BottomNavigationBar项目:

 View view = bottomNavigationView.findViewById(R.id.menu_action_item); view.performClick(); 

这将正确地安排所有项目的标签。

这可能会在即将更新中添加。 但在此期间,要完成这个,你可以使用reflection。

创build一个从BottomNavigationView扩展的自定义视图,并访问它的一些字段。

 public class SelectableBottomNavigationView extends BottomNavigationView { public SelectableBottomNavigationView(Context context) { super(context); } public SelectableBottomNavigationView(Context context, AttributeSet attrs) { super(context, attrs); } public SelectableBottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setSelected(int index) { try { Field f = BottomNavigationView.class.getDeclaredField("mMenuView"); f.setAccessible(true); BottomNavigationMenuView menuView = (BottomNavigationMenuView) f.get(this); try { Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE); method.setAccessible(true); method.invoke(menuView, index); } catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } } } 

然后在你的xml布局文件中使用它。

 <com.your.app.SelectableBottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="wrap_content" app:itemBackground="@color/primary" app:itemIconTint="@drawable/nav_item_color_state" app:itemTextColor="@drawable/nav_item_color_state" app:menu="@menu/bottom_navigation_menu"/> 

https://stackoverflow.com/a/40778162/2571249试试我的解决scheme

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bottomNavigationView.setOnNavigationItemSelectedListener(this); Menu menu = bottomNavigationView.getMenu(); this.onNavigationItemSelected(menu.findItem(R.id.action_favorites)); } 

现在可以从25.3.0版本调用setSelectedItemId() \ o /

似乎被修复在SupportLibrary 25.1.0 :)编辑:这似乎是固定的,select的状态保存,当旋转屏幕。

我不想修改你的代码。 如果是这样,我build议你尝试BottomNavigationViewEx 。

你只需要调用一个方法setCurrentItem(index);getCurrentItem()

点击这里查看图像

只是增加另一种方式来进行编程select – 这可能是第一位的意图或稍后添加。

 Menu bottomNavigationMenu = myBottomNavigationMenu.getMenu(); bottomNavigationMenu.performIdentifierAction(selected_menu_item_id, 0); 

performIdentifierAction一个Menu项ID和一个标志。

有关更多信息,请参阅文档 。

反思是个坏主意。

去这个主意 。 有一个方法执行select,但也调用callback:

  @CallSuper public void setSelectedItem(int position) { if (position >= getMenu().size() || position < 0) return; View menuItemView = getMenuItemView(position); if (menuItemView == null) return; MenuItemImpl itemData = ((MenuView.ItemView) menuItemView).getItemData(); itemData.setChecked(true); boolean previousHapticFeedbackEnabled = menuItemView.isHapticFeedbackEnabled(); menuItemView.setSoundEffectsEnabled(false); menuItemView.setHapticFeedbackEnabled(false); //avoid hearing click sounds, disable haptic and restore settings later of that view menuItemView.performClick(); menuItemView.setHapticFeedbackEnabled(previousHapticFeedbackEnabled); menuItemView.setSoundEffectsEnabled(true); mLastSelection = position; } 
 private void setSelectedItem(int actionId) { Menu menu = viewBottom.getMenu(); for (int i = 0, size = menu.size(); i < size; i++) { MenuItem menuItem = menu.getItem(i); ((MenuItemImpl) menuItem).setExclusiveCheckable(false); menuItem.setChecked(menuItem.getItemId() == actionId); ((MenuItemImpl) menuItem).setExclusiveCheckable(true); } } 

解决scheme中唯一的“减号”是使用MenuItemImpl ,它是库的“内部”(尽pipe是公共的)。

我向Google提出了一个错误,那就是在BottomNavigationView上没有可靠的方法来select页面: https : //code.google.com/p/android/issues/detail? id = 233697

NavigationView显然有一个类似的问题,他们通过添加一个新的setCheckedItem()方法来解决这个问题。