android bottomnavigationview

Establecer elemento seleccionado en Android BottomNavigationView



(16)

Agregue android:enabled="true" a BottomNavigationMenu Items.

Y luego establezca bottomNavigationView.setOnNavigationItemSelectedListener(mListener) y bottomNavigationView.setOnNavigationItemSelectedListener(mListener) como seleccionado haciendo bottomNavigationView.selectedItemId = R.id.your_menu_id

Estoy usando el nuevo android.support.design.widget.BottomNavigationView de la biblioteca de soporte. ¿Cómo puedo configurar la selección actual del código? Me di cuenta de que la selección vuelve a cambiar al primer elemento, después de girar la pantalla. Por supuesto, también ayudaría, si alguien pudiera decirme, cómo "guardar" el estado actual de BottomNavigationView en la función onPause y cómo restaurarlo en onResume .

¡Gracias!


Ahora es posible desde la versión setSelectedItemId() llamar a setSelectedItemId() / o /


Cometí un error en Google sobre el hecho de que no hay una forma confiable de seleccionar la página en BotViewNavigationView: https://code.google.com/p/android/issues/detail?id=233697

NavigationView aparentemente tuvo un problema similar, que solucionaron al agregar un nuevo método setCheckedItem ().


Desde la API 25.3.0 se introdujo el método setSelectedItemId(int id) que le permite marcar un elemento como seleccionado como si hubiera sido tocado.

De documentos:

Establece la ID del elemento del menú seleccionado. Esto se comporta igual que tocar un elemento.

Ejemplo de código:

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

IMPORTANTE

DEBE haber agregado todos los elementos al menú y configurar el Listener antes de llamar a setSelectedItemId para que BottomNavigationView pueda ejecutar el comportamiento del código correspondiente. Si llama a setSelectedItemId antes de agregar los elementos del menú y configurar el oyente, no sucederá nada.


Esto probablemente se agregará en las próximas actualizaciones. Pero mientras tanto, para lograr esto puedes usar la reflexión.

Cree una vista personalizada que se extienda desde BottomNavigationView y acceda a algunos de sus campos.

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

Y luego úselo en su archivo de diseño 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"/>


Para hacer clic programáticamente en el elemento BottomNavigationBar que necesita usar:

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

Esto organiza todos los artículos con sus etiquetas correctamente.


Parece estar arreglado en SupportLibrary 25.1.0 :) Editar: Parece arreglado que el estado de la selección se guarda al girar la pantalla.


Por encima de API 25, puede usar setSelectedItemId (menu_item_id) pero bajo API 25 debe hacer de manera diferente, Menú de usuario para obtener el identificador y luego establecer Chequeado en Elemento específico verificado


Puedes probar el método performClick:

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


Si no quieres modificar tu código. Si es así, te recomendé que pruebes BottomNavigationViewEx

Solo necesita reemplazar llamar a un método setCurrentItem(index); y getCurrentItem()


Simplemente agregue otra forma de realizar una selección programáticamente: esta es probablemente la intención en primer lugar o tal vez esto se agregó más adelante.

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

performIdentifierAction toma una identificación de elemento de Menu y una bandera.

Vea la documentation para más información.


La reflexión es mala idea.

Dirígete a esta gist . Hay un método que realiza la selección pero también invoca la devolución de llamada:

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


Para aquellos que todavía usan SupportLibrary <25.3.0

No estoy seguro de si esta es una respuesta completa a esta pregunta, pero mi problema fue muy similar: tuve que procesar presionar el botón back y llevar al usuario a la pestaña anterior donde estaba. Entonces, tal vez mi solución sea útil para alguien:

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

Tenga en cuenta que si el usuario presiona otra pestaña de navegación BottomNavigationView no borrará el elemento seleccionado actualmente, por lo que debe llamar a este método en onNavigationItemSelected después de procesar la acción de navegación:

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

Con respecto al almacenamiento del estado de instancia, creo que podría jugar con el mismo action id de action id de la vista de navegación y encontrar la solución adecuada.


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

El único ''menos'' de la solución es usar MenuItemImpl , que es ''interno'' a la biblioteca (aunque público).


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


bottomNavigationView.setSelectedItemId(R.id.action_item1);

donde action_item1 es la ID del elemento del menú.