web-dev-qa-db-fra.com

Définir l'index/l'ID d'élément initialement sélectionné dans BottomNavigationView

J'ai implémenté le nouveau BottomNavigationView ((com.Android.support:design:25.0.0) et je ne sais pas comment définir un index de sélection ou un MenuItem id (dans mon cas, l'élément moyen devrait être sélectionné par défaut). Je crains qu'il n'y ait aucune possibilité pour le moment car c'est encore trop cru, mais de toute façon, toute aide sera appréciée. Merci!

24
UneXp

Définissez l'ID d'élément de menu sélectionné à l'aide de setSelectedItemId :

bottomNavigationView.setSelectedItemId(R.id.item_id);

Cette méthode a commencé à être disponible à partir de Android Support Library 25.3.0.

25
user5968678

La seule solution qui a fonctionné pour moi est la suivante:

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

Effectuer un clic suffit. J'espère que nous aurons des méthodes/propriétés supplémentaires dans les prochaines versions.

UPD:

Comme user5968678mentionné , une nouvelle méthode a été ajoutée depuis Android Support Library v25.3.0:

bottomNavigationView.setSelectedItemId(R.id.item_id);

alors utilisez plutôt :)

46
UneXp

Je pense que cette solution peut être légèrement plus élégante qu’une réponse acceptée:

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

où menuItemIndex est l'index de l'élément sélectionné.

15
Jan Slominski

Voici ce que la documentation en dit:

Les éléments de menu peuvent également être utilisés pour sélectionner par programme la destination actuellement active. Cela peut être fait en utilisant MenuItem#setChecked(true)

Au lieu de ce que Jan a posté, vous pouvez également trouver l'article par identifiant:

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

De plus, je peux recommander d'appeler .callOnClick() AU LIEU DE .performClick() .

5
arekolek

Si vous utilisez un auditeur, comme l'implémentation par défaut dans Android studio, essayez ceci:

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

Arrêtez d'utiliser Reflection! C'est mauvais! 

Bien que la bibliothèque de support ne nous donne pas la possibilité de sélectionner l’élément de la BottomNavigationView à afficher lors de sa première apparition lorsqu’il est visible, nous avons deux possibilités:

Tout d'abord, en utilisant la boucle:

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

Deuxièmement, sans boucle mais avec une variable de classe (car la logique est faite depuis la classe interne):

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;

Lorsque la méthode setupBottomNavigationView () est exécutée? Dans la méthode Activity onCreate (), regardez:

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

Simple et sans code étendu.

J'espère que ça aide!

1

Code Kotlin pour l'élément sélectionné initial dans bottomnavigation.BottomNavigationView:

bottom_navigation_view.selectedItemId = R.id.navigation_item_messages
0
Hamed Jaliliani

Vous pouvez étendre BottomNavigationView et utiliser la réflexion pour appeler des méthodes privées.

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

}
0
cpienovi