19

Zaimplementowałem nowy BottomNavigationView (com.android.support:design:25.0.0) i nie mam pojęcia, jak ustawić indeks wyboru lub identyfikator MenuItem id (w moim przypadku, pozycja środkowa powinien być wybrany domyślnie). Obawiam się, że na razie nie ma takiej możliwości, o ile jest jeszcze zbyt surowa, ale i tak wszelka pomoc zostanie doceniona. Dzięki!Ustaw początkowo wybrany indeks elementu/identyfikator w BottomNavigationView

+1

sprawdź ten link. http://androidgifts.com/build-android-material-design-bottom-navigation/ –

+0

Tak wiem o [BottomBar] (https://github.com/roughike/BottomBar), ale nie mogę uwierzyć, że support.design nie ma możliwości programowego wybierania elementów :) Może jakieś hackowate rozwiązania ... – UneXp

+0

Spójrz na [tę odpowiedź] (http://stackoverflow.com/a/40244165/2215962). To najlepsze rozwiązanie. –

Odpowiedz

12

Set ID wybrany element menu za pomocą setSelectedItemId:

bottomNavigationView.setSelectedItemId(R.id.item_id); 

Metoda ta zaczęła być dostępne z Android Wsparcia Biblioteka 25.3.0.

44

Jedynym rozwiązaniem, że pracował dla mnie jest:

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

Wystarczy wykonywania kliknięcie załatwia sprawę. Mam nadzieję, że będziemy mieć dodatkowe metody/właściwości w przyszłych wydaniach.

UPD:

Jak user5968678mentioned, nowa metoda została dodana, ponieważ Android Wsparcia Biblioteki v25.3.0:

bottomNavigationView.setSelectedItemId(R.id.item_id); 

więc używać w zamiast :)

+3

Najlepsze rozwiązanie jeszcze – Meanman

-1

można rozszerzyć BottomNavigationView i użyj refleksji, aby wywołać prywatne metody.

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

Odbicie to zły pomysł! –

1

Przestań używać refleksji! To jest złe!

Cóż, natomiast biblioteka wsparcie nie daje nam możliwość wyboru elementu z BottomNavigationView być wyświetlany na pierwszy raz, gdy jest on widoczny, mamy dwie możliwości:

pierwsze, stosując pętla:

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

drugie bez pętli ale ze zmienną klasy (ponieważ układ logiczny jest wykonane od wewnątrz wewnętrznej klasy)

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; 

Gdy setupBottomNavigationView() metoda jest wykonywana? W metodzie aktywność onCreate() spojrzeć:

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

prosty i bez znacznego kodu.

Mam nadzieję, że pomoże!

0

Spróbuj kod

@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

Myślę, że to rozwiązanie moich być nieco bardziej eleganckie niż zaakceptowanej odpowiedzi:

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

gdzie menuItemIndex jest indeks wybranego elementu.

+1

Nie działa. Jeśli masz włączoną animację na dolnym pasku nawigacyjnym, możesz zobaczyć, że kolor został zmieniony na wybranym elemencie, ale animacja nadal znajduje się na pierwszym elemencie menu. Niedostępny na razie w wersji na Androida. JEŚLI CHCESZ, ABY DZIAŁAŁA W DOWOLNYM MIEJSCU: ((BottomNavigationMenuView) bottomNavigationView.getChildAt (0)). GetChildAt (menuItemIndex) .performClick(); LUB NAWET LEPSZE: ((BottomNavigationMenuView) bottomNavigationView.getChildAt (0)). FindViewById (R.id.id_menu_action) .performClick(); –

+0

Czy możesz opublikować swój kod? Używam najnowszego BottomNavigationView z biblioteki wsparcia google (25.1.0) i kiedy zmienię wybrany indeks, animacja działa bez problemów. –

4

Oto co the documentation mówi o tym:

pozycje menu mogą być również wykorzystywane do miejsca przeznaczenia, które programowo wyboru jest aktualnie aktywny. Można to zrobić za pomocą MenuItem#setChecked(true)

Jako alternatywę dla tego, co Jan pisał, można również znaleźć element o id:

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

Również mogę polecić nazywając .callOnClick() instead of .performClick().

0

Jeśli używasz słuchacza, jak domyślnej implementacji w android studio, spróbuj tego:

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