Установить первоначально выбранный индекс/идентификатор элемента в BottomNavigationView

Я внедрил BottomNavigationView и не знаю, как установить индекс выбора или MenuItem id (в моем случае по умолчанию должен быть выбран средний элемент).

Боюсь, пока такой возможности нет, так как она еще слишком сырая, но в любом случае любая помощь будет оценена. Спасибо!


comment
Обратитесь по этой ссылке. androidgifts.com/   -  person Jigar Shekh    schedule 25.10.2016
comment
Да, я знаю о BottomBar, но я не могу поверить, что у support.design нет возможности программно выбирать элементы :) Может быть, какие-то хакерские решения...   -  person UneXp    schedule 25.10.2016
comment
Посмотрите на этот ответ. Это лучшее решение.   -  person Volodymyr Yatsykiv    schedule 13.12.2016
comment
Добавлен более элегантный ответ, вы можете проверить его.   -  person Jan Slominski    schedule 14.01.2017


Ответы (11)



Единственное решение, которое сработало для меня, это:

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

Простое нажатие делает свое дело. Надеюсь, мы получим дополнительные методы/свойства в будущих выпусках.

ОБНОВЛЕНИЕ:

Как упоминалось user5968678 , начиная с Android Support Library v25.3.0, был добавлен новый метод:

bottomNavigationView.setSelectedItemId(R.id.item_id);

так что используйте это вместо :)

person UneXp    schedule 25.10.2016
comment
Лучшее решение - person Meanman; 14.12.2016

Я думаю, что это решение может быть немного более элегантным, чем принятый ответ:

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

где menuItemIndex — индекс выбранного элемента.

person Jan Slominski    schedule 14.01.2017
comment
Не работает. Если у вас включена анимация на нижней панели навигации, вы можете видеть, что цвет выбранного элемента был изменен, но анимация все еще находится в первом пункте меню. На данный момент недоступно в Android lib. ЕСЛИ ВЫ ХОТИТЕ, ЧТОБЫ ЭТО РАБОТАЛО В ЛЮБОМ СЛУЧАЕ: ((BottomNavigationMenuView) bottomNavigationView.getChildAt(0)).getChildAt(menuItemIndex).performClick(); ИЛИ ЕЩЕ ЛУЧШЕ: ((BottomNavigationMenuView) bottomNavigationView.getChildAt(0)).findViewById(R.id.id_menu_action).performClick(); - person Anne-Claire; 30.01.2017
comment
Можете ли вы опубликовать свой код? Я использую последнюю версию BottomNavigationView из библиотеки поддержки Google (25.1.0), и когда я меняю выбранный индекс таким образом, анимация работает без проблем. - person Jan Slominski; 31.01.2017
comment
это только сделает меню активным, но не вызовет само меню, что я и ищу - person Irfandi D. Vendy; 23.07.2019

Вот что говорит об этом документация:

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

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

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

Также в целом я могу порекомендовать вызывать .callOnClick() вместо .performClick().

person arekolek    schedule 08.03.2017

Если вы используете прослушиватель, например реализацию по умолчанию в студии Android, попробуйте следующее:

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

Я считаю, что вопрос в этом контексте рассматривается в разных контекстах на основе ответов здесь. Согласно оценке, требуется способность сосредоточиться на конкретном элементе BottomNavigationView (определенно в новом классе, содержащем разные фрагменты).

Теперь у вас могут быть кнопки BottomNavigationView ИЛИ или что-либо, что можно щелкнуть, чтобы запустить новую активность по намерению: - т.е.

Intent intent = new Intent(getActivity(), New_Activity.class);
    intent.putExtra("EXTRA_PAGE, 1);
    startActivityForResult(intent, 30);

Затем - в нашей New_Activity мы получаем намерение-

Намерение намерение = getIntent(); int page = намерение.getExtras().getInt("EXTRA_PAGE);

Затем мы перебираем переменную страницы, чтобы найти номер/индекс, для которого отражается текущий BottomNavigationView, ЗАТЕМ мы устанавливаем наш пункт меню фокуса (при условии, что ваш BottomNavigationView имеет Пункт меню для его отображения)

     if(page == 1) {
         currentselect = new Pending();
            bottomNavigationView.getMenu().getItem(0).setChecked(true);
}

Это отвечает на вопрос выше. Остальная часть переключателя Fragment хорошо обрабатывается количеством сообщений выше, вызывая:

bottomNavigationView.setOnNavigationItemSelectedListener(navListener);

Затем что-то вроде:

   private BottomNavigationView.OnNavigationItemSelectedListener navListener =
        new BottomNavigationView.OnNavigationItemSelectedListener(){
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                Fragment selectedFrag = null;
                switch (item.getItemId()) {
                    case R.id.pending:
                        selectedFrag = new Pending();
                        break;
                    case R.id.onTransmit:
                        selectedFrag = new inTransmit();
                        break;
                    case R.id.complete:
                        selectedFrag = new Complete();
                        break;
                }

                getSupportFragmentManager().beginTransaction().replace(R.id.select_field, selectedFrag).commit();

                return true;
            }
        };

ПРИМЕЧАНИЕ. Использование BottomNavigationView и ContentFrameLayout слишком экономично и сократит ваш код более чем на 50 %, в отличие от использования подобных ViewPager и < strong>Вкладка

person Mbanda    schedule 12.12.2018

Код Kotlin для начального выбранного элемента в bottomnavigation.BottomNavigationView:

bottom_navigation_view.selectedItemId = R.id.navigation_item_messages
person Hamed Jaliliani    schedule 19.01.2019

Прекратите использовать 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()? В методе Activity onCreate() посмотрите:

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

Просто и без обширного кода.

Надеюсь, поможет!

person Filipe Brito    schedule 29.10.2016

Вы можете добиться этого эффекта, добавив фиктивный элемент меню в качестве первого элемента в меню, которое вы назначаете BottomNavigationView, и установив этот элемент как невидимый. Затем в обработчике повторного выбора вызовите setSelectedItem(dummy) для фиктивного элемента. В результате видимые пункты меню будут вести себя как виртуальные переключатели. Мне потребовалось больше работы, чем следовало бы, чтобы понять это. Вам нужно будет сделать это так, чтобы setSelectItem вызывался после завершения повторного выбора:

@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
    anyView.post(new Runnable() {
        @Override
        public void run() {
            navigationView.setSelectedItemId(R.id.action_dummy);
        }
    }
});
person Steven Chartley    schedule 09.11.2020

Вы можете расширить 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);
    }

}
person cpienovi    schedule 29.10.2016
comment
Рефлексия - плохая идея! - person Filipe Brito; 29.10.2016

Реализуйте BottomNavigationView.OnNavigationItemSelectedListener и установите selectedItemId при инициализации.

this.bottomNavigationView.setOnNavigationItemSelectedListener {
    val targetFragment = when (menuItem.itemId) {
        R.id.action_home -> {
            HomeFragment()
        }
        R.id.action_post -> {
            PostFragment()
        }
        R.id.action_settings -> {
            SettingsFragment()
        }
        else -> null
    }
    targetFragment?.let {
        this.activity?.supportFragmentManager?.transaction {
            replace(R.id.containerLayout, it, it.javaClass.simpleName)
        }
    }
    true
}

this.bottomNavigationView.selectedItemId = R.id.action_home
person Morgan Koh    schedule 24.04.2019