Я внедрил новый BottomNavigationView (com.android.support:design:25.0.0) и понятия не имею, как установить индекс выбора или MenuItem
id (в моем случае средний элемент должен быть выбран по умолчанию). Я боюсь, что такой возможности пока нет, поскольку она еще слишком сырая, но в любом случае любая помощь будет оценена. Благодаря!Установить первоначально выбранный индекс/id объекта в BottomNavigationView
ответ
Установить выбранный пункт меню ID с помощью setSelectedItemId
:
bottomNavigationView.setSelectedItemId(R.id.item_id);
Этот метод начал быть доступны из Android поддержки библиотеки 25.3.0.
Единственное решение, которое работало для меня:
View view = bottomNavigationView.findViewById(R.id.menu_action_dashboard);
view.performClick();
Просто выполняя щелчок делает трюк. Надеюсь, у нас будут дополнительные методы/свойства в будущих выпусках.
UPD:
Как user5968678mentioned, новый метод был добавлен начиная с Android библиотеки поддержки v25.3.0:
bottomNavigationView.setSelectedItemId(R.id.item_id);
так использовать в вместо :)
Лучшее решение еще – Meanman
Вы можете расширить 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);
}
}
Отражение - плохая идея! –
Остановить использование 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();
}
Простой и без обширного кода.
Надеюсь, это поможет!
Попробуйте этот код
@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.getMenu().getItem(menuItemIndex).setChecked(true)
где menuItemIndex является индекс выбранного элемента.
Не работает. Если на вашем нижнем навигационном блоке активирована анимация, вы можете увидеть, что цвет был изменен на выбранном элементе, но анимация по-прежнему находится в первом элементе меню. Пока недоступно в android lib. ЕСЛИ ВЫ ХОТИТЕ СДЕЛАТЬ ЭТО РАБОТУ В любое время: ((BottomNavigationMenuView) bottomNavigationView.getChildAt (0)). GetChildAt (menuItemIndex) .performClick(); ИЛИ ДАЖЕ ЛУЧШЕ: ((BottomNavigationMenuView) bottomNavigationView.getChildAt (0)). FindViewById (R.id.id_menu_action) .performClick(); –
Можете ли вы разместить свой код? Я использую последнюю версию BottomNavigationView из библиотеки поддержки google (25.1.0), и когда я меняю выбранный индекс так, что анимация работает без проблем. –
Вот что the documentation говорит об этом:
Пункты меню можно также использовать для выбора программно которых назначения в настоящее время активен. Это может быть сделано с помощью
MenuItem#setChecked(true)
В качестве альтернативы тому, что писал Ян, вы можете также найти элемент по идентификатору:
Menu menu = findViewById(R.id.navigation).getMenu();
menu.findItem(R.id.navigation_home).setChecked(true);
Кроме того, я могу рекомендовать вызов .callOnClick()
instead of .performClick()
.
Если вы используете слушатель, как реализация по умолчанию в Android Studio, попробуйте следующее:
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
Integer indexItem = 4;
navigation.getMenu().getItem(indexItem).setChecked(true);
mOnNavigationItemSelectedListener.onNavigationItemSelected(navigation.getMenu().getItem(indexItem));
См эту ссылку. http://androidgifts.com/build-android-material-design-bottom-navigation/ –
Да, я знаю о [BottomBar] (https://github.com/roughike/BottomBar), но я не могу поверить, что support.design у одного нет возможности выбирать элементы программно :) Возможно, некоторые хакерские решения ... – UneXp
Посмотрите на [этот ответ] (http://stackoverflow.com/a/40244165/2215962). Это лучшее решение. –