19

Я внедрил новый BottomNavigationView (com.android.support:design:25.0.0) и понятия не имею, как установить индекс выбора или MenuItem id (в моем случае средний элемент должен быть выбран по умолчанию). Я боюсь, что такой возможности пока нет, поскольку она еще слишком сырая, но в любом случае любая помощь будет оценена. Благодаря!Установить первоначально выбранный индекс/id объекта в BottomNavigationView

+1

См эту ссылку. http://androidgifts.com/build-android-material-design-bottom-navigation/ –

+0

Да, я знаю о [BottomBar] (https://github.com/roughike/BottomBar), но я не могу поверить, что support.design у одного нет возможности выбирать элементы программно :) Возможно, некоторые хакерские решения ... – UneXp

+0

Посмотрите на [этот ответ] (http://stackoverflow.com/a/40244165/2215962). Это лучшее решение. –

ответ

12

Установить выбранный пункт меню ID с помощью setSelectedItemId:

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

Остановить использование Reflection! Это плохо!

Ну, а библиотека поддержки не дает нам возможность выбрать элемент из 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

Не работает. Если на вашем нижнем навигационном блоке активирована анимация, вы можете увидеть, что цвет был изменен на выбранном элементе, но анимация по-прежнему находится в первом элементе меню. Пока недоступно в android lib. ЕСЛИ ВЫ ХОТИТЕ СДЕЛАТЬ ЭТО РАБОТУ В любое время: ((BottomNavigationMenuView) bottomNavigationView.getChildAt (0)). GetChildAt (menuItemIndex) .performClick(); ИЛИ ДАЖЕ ЛУЧШЕ: ((BottomNavigationMenuView) bottomNavigationView.getChildAt (0)). FindViewById (R.id.id_menu_action) .performClick(); –

+0

Можете ли вы разместить свой код? Я использую последнюю версию BottomNavigationView из библиотеки поддержки google (25.1.0), и когда я меняю выбранный индекс так, что анимация работает без проблем. –

4

Вот что the documentation говорит об этом:

Пункты меню можно также использовать для выбора программно которых назначения в настоящее время активен. Это может быть сделано с помощью MenuItem#setChecked(true)

В качестве альтернативы тому, что писал Ян, вы можете также найти элемент по идентификатору:

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