19

我已经实现了新的BottomNavigationView(com.android.support:design:25.0.0),并不知道如何设置选择索引或MenuItem id(在我的情况中,应该被默认选中)。恐怕现在没有这种可能性,只要它太原始了,但无论如何,任何帮助将不胜感激。谢谢!在BottomNavigationView中设置最初选择的项索引/ ID

+1

请参阅此链接。 http://androidgifts.c​​om/build-android-material-design-bottom-navigation/ –

+0

是的,我知道[BottomBar](https://github.com/roughike/BottomBar),但我无法相信support.design的一个没有可能以编程方式选择项目:)也许一些hacky解决方案... – UneXp

+0

看看[这个答案](http://stackoverflow.com/a/40244165/2215962)。这是最好的解决方案。 –

回答

12

设置使用setSelectedItemId选择的菜单项ID:

bottomNavigationView.setSelectedItemId(R.id.item_id); 

这种方法开始,购自Android的支持库25.3.0。

44

为我工作,唯一的解决办法是:

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

只需执行点击的伎俩。希望我们在未来的版本中会有更多的方法/属性。

UPD:

由于user5968678mentioned,由于Android支持库v25.3.0加入新的方法:

bottomNavigationView.setSelectedItemId(R.id.item_id); 

所以使用,而不是:)

+3

最佳解决方案 – Meanman

-1

您可以扩展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 { 
      BottomNavigationMenuView menuView = (BottomNavigationMenuView) getField(BottomNavigationView.class, "mMenuView"); 
      OnNavigationItemSelectedListener listener = (OnNavigationItemSelectedListener) getField(BottomNavigationView.class, "mListener"); 
      try { 
       Method method = menuView.getClass().getDeclaredMethod("activateNewButton", Integer.TYPE); 
       method.setAccessible(true); 
       // activate item. 
       method.invoke(menuView, index); 
       if (listener != null) { 
        // trigger item select event. 
        listener.onNavigationItemSelected(getMenu().getItem(index)); 
       } 
      } catch (SecurityException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 
       e.printStackTrace(); 
      } 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } catch (NoSuchFieldException e) { 
      e.printStackTrace(); 
     } 
    } 

    private Object getField(Class clazz, String fieldName) throws NoSuchFieldException, IllegalAccessException { 
     Field f = clazz.getDeclaredField(fieldName); 
     f.setAccessible(true); 
     return f.get(this); 
    } 

} 
+1

反射是一个坏主意! –

1

停止使用反射!这是坏的!

好,而支持库不给我们上显示时,它是可见的第一次选择从BottomNavigationView项目的选择,我们有两种可能性:

首先,用循环:

private void setupBottomNavigationView() { 
    // Get the menu from our navigationBottomView. 
    Menu bottomNavigationViewMenu = bottomNavigationView.getMenu(); 
    // Uncheck the first menu item (the default item which is always checked by the support library is at position 0). 
    bottomNavigationMenu.findItem(R.id.action_one).setChecked(false); 
    // Check the wished first menu item to be shown to the user. 
    bottomNavigationMenu.findItem(R.id.action_two).setChecked(true); 

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { 
     @Override 
     public boolean onNavigationItemSelected(@NonNull MenuItem item) { 

    Menu bottomNavigationMenu = bottomNavigationView.getMenu(); 
      for (int i = 0; i < bottomNavigationMenu.size(); i++) { 
       if (item.getItemId() != bottomNavigationMenu.getItem(i).getItemId()) { 
        bottomNavigationMenu.getItem(i).setChecked(false); 
       } 
      } 

      switch (item.getItemId()) { 
       case R.id.action_one : 
        replaceFragment(new OneFragment()); 
        break; 
       case R.id.action_two : 
        replaceFragment(new TwoFragment()); 
        break; 
       case R.id.action_three : 
        replaceFragment(new ThreeFragment()); 
        break; 
      } 
      return false; 
     } 
    }); 
} 

其次,不循环,但与类变量(因为所述逻辑被从内部类内完成):

private void setupBottomNavigationView() { 
    // Get the menu from our navigationBottomView. 
    Menu bottomNavigationViewMenu = bottomNavigationView.getMenu(); 
    // Uncheck the first menu item (the default item which is always checked by the support library is at position 0). 
    bottomNavigationViewMenu.findItem(R.id.action_one).setChecked(false); 
    // Check the wished first menu item to be shown to the user. Also store that menu item on a variable to control when a menu item must be unchecked. 
    mActiveBottomNavigationViewMenuItem = bottomNavigationViewMenu.findItem(R.id.action_two).setChecked(true); 

    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { 
     @Override 
     public boolean onNavigationItemSelected(@NonNull MenuItem selectedMenuItem) { 
      switch (selectedMenuItem.getItemId()) { 
       case R.id.action_one : 
        replaceFragment(new OneFragment()); 
        break; 
       case R.id.action_two : 
        replaceFragment(new TwoFragment()); 
        break; 
       case R.id.action_three : 
        replaceFragment(new ThreeFragment()); 
        break; 
      } 

      if (selectedMenuItem != mActiveBottomNavigationViewMenuItem){ 
       mActiveBottomNavigationViewMenuItem.setChecked(false); 
       mActiveBottomNavigationViewMenuItem = selectedMenuItem; 
      } 

      return false; 
     } 
    }); 
} 

private MenuItem mActiveBottomNavigationViewMenuItem; 

当setupBottomNavigationView()方法被执行?在活动onCreate()方法,看看:

@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    // ... 
    setupBottomNavigationView(); 
} 

简单而不需要大量的代码。

希望它有帮助!

0

试试这个代码

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

    bottomNavigationView.setOnNavigationItemSelectedListener(this); 
    Menu menu = bottomNavigationView.getMenu(); 
    this.onNavigationItemSelected(menu.findItem(R.id.action_favorites)); 
} 
8

我觉得这种解决方案我是略高于接受的答案更优雅:

bottomNavigationView.getMenu().getItem(menuItemIndex).setChecked(true) 

其中menuItemIndex是所选元素的索引。

+1

不起作用。如果您在bottomNavigationBar上启用了动画,则可以看到所选项目上的颜色已更改,但动画仍在第一个菜单项上。现在在android lib中不可用。如果你想让它工作:((BottomNavigationMenuView)bottomNavigationView.getChildAt(0)).getChildAt(menuItemIndex).performClick();或者甚至更好:((BottomNavigationMenuView)bottomNavigationView.getChildAt(0))。findViewById(R.id.id_menu_action).performClick(); –

+0

你可以发布你的代码吗?我使用谷歌支持库(25.1.0)的最新BottomNavigationView,当我改变选定的索引时,动画没有问题。 –

4

这里是the documentation说一下:

菜单项也可用于编程方式选择哪个目的地是当前活动。它可以通过MenuItem#setChecked(true)

作为替代到什么一月发布来完成,也可以通过ID找到该项目:

Menu menu = findViewById(R.id.navigation).getMenu(); 
menu.findItem(R.id.navigation_home).setChecked(true); 

而且,我可以推荐打电话.callOnClick() instead of .performClick()

0

如果您使用监听器,像在Android Studio中默认的实现,试试这个:

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation); 
Integer indexItem = 4; 
navigation.getMenu().getItem(indexItem).setChecked(true); 
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem)); 
相关问题