Как выделить элемент при нажатии, используя BottomNavigationView между действиями?
Я добавил Нижнее навигационное представление для своего приложения, но мне нужно Нижнее навигационное представление между действиями, а не фрагментом, поэтому я добавил этот код в Java для всех трех моих действий.
Когда я выбираю "Второй" или "Третий" в своем телефоне, все происходит правильно, но проблема в том, что основной момент переходит к пункту "Первый".
Мне нужно выделить пункт, который я нажимаю.
Я использовал фрагмент, и он отлично работает, но я все еще начинаю использовать фрагмент, поэтому я использую действия.
Первый код активности:
BottomNavigationView mBottomNavigation;
mBottomNavigation =(BottomNavigationView) findViewById(R.id.BottomNavigator);
mBottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.Nav_Second:
Intent Second= new Intent(First.this, Second.class);
startActivity(Second);
break;
case R.id.Nav_Third:
Intent Third= new Intent(First.this, Third.class);
startActivity(Third);
break;
}
return true;
}
});
}}
Второе мероприятие:
BottomNavigationView mBottomNavigation;
mBottomNavigation =(BottomNavigationView) findViewById(R.id.BottomNavigator);
mBottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.Nav_First:
Intent First= new Intent(Second.this, First.class);
startActivity(First);
break;
case R.id.Nav_Third:
Intent Third= new Intent(Second.this, Third.class);
startActivity(Third);
break;
}
return true;
}
});
}}
Третий вид деятельности:
BottomNavigationView mBottomNavigation;
mBottomNavigation =(BottomNavigationView) findViewById(R.id.BottomNavigator);
mBottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.Nav_First:
Intent First= new Intent(Third.this, First.class);
startActivity(First);
break;
case R.id.Nav_Second:
Intent Second= new Intent(Third.this, Second.class);
startActivity(Second);
break;
}
return true;
}
});
}}
XML одинаковы для 3 видов деятельности:
<android.support.design.widget.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/BottomNavigator"
android:background="@color/colorPrimaryDark"
android:layout_alignParentBottom="true"
app:itemTextColor="@drawable/item_bg"
app:itemIconTint="@drawable/item_bg"
app:menu="@menu/navigate_items">
</android.support.design.widget.BottomNavigationView>
Ответы
Ответ 1
Вы можете использовать BottomNavigationView с действиями, представляющими вкладки. Ключ состоит в том, чтобы повторить компонент навигационного представления в каждом действии и иметь код каждого действия, управляющего компонентом навигации: запуск правильной активности при нажатии на клики навигационных элементов и выбор правильного элемента навигации после начала действия.
Вам нужно запустить вновь выбранные действия (вкладки) с задержкой, чтобы разрешить анимацию переключения вкладок до того, как новая активность заменит предыдущую.
Мой подход заключался в том, чтобы все действия, представляющие вкладки, наследовались от одного и того же класса BaseActivity, реализующего общее поведение.
Это код примера BaseActivity:
public abstract class BaseActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {
protected BottomNavigationView navigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
navigationView = (BottomNavigationView) findViewById(R.id.navigation);
navigationView.setOnNavigationItemSelectedListener(this);
}
@Override
protected void onStart() {
super.onStart();
updateNavigationBarState();
}
// Remove inter-activity transition to avoid screen tossing on tapping bottom navigation items
@Override
public void onPause() {
super.onPause();
overridePendingTransition(0, 0);
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
navigationView.postDelayed(() -> {
int itemId = item.getItemId();
if (itemId == R.id.navigation_home) {
startActivity(new Intent(this, HomeActivity.class));
} else if (itemId == R.id.navigation_dashboard) {
startActivity(new Intent(this, DashboardActivity.class));
} else if (itemId == R.id.navigation_notifications) {
startActivity(new Intent(this, NotificationsActivity.class));
}
finish();
}, 300);
return true;
}
private void updateNavigationBarState(){
int actionId = getNavigationMenuItemId();
selectBottomNavigationBarItem(actionId);
}
void selectBottomNavigationBarItem(int itemId) {
Menu menu = navigationView.getMenu();
for (int i = 0, size = menu.size(); i < size; i++) {
MenuItem item = menu.getItem(i);
boolean shouldBeChecked = item.getItemId() == itemId;
if (shouldBeChecked) {
item.setChecked(true);
break;
}
}
}
abstract int getContentViewId();
abstract int getNavigationMenuItemId();
}
Это мой весь пример, основанный на шаблоне активности Android Android Bottom Navigation:
https://github.com/ddekanski/BottomNavigationViewBetweenActivities
Ответ 2
Для тех, кто все еще ищет это, @javazian ответ на продление каждого вида деятельности, по моему мнению, является излишним.
Более сжатое решение состоит в том, чтобы восстановить навигационное меню и вручную проверить соответствующий пункт меню.
Обратите внимание, что в приведенном ниже примере INSERT_INDEX_HERE необходимо заменить индексом пункта меню (например, в элементе меню слева внизу будет указатель 0).
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connections);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
// Ensure correct menu item is selected (where the magic happens)
Menu menu = navigation.getMenu();
MenuItem menuItem = menu.getItem(INSERT_INDEX_HERE);
menuItem.setChecked(true);
}
Ответ 3
Вы абсолютно можете использовать BottomNavigationView с действиями, но это не рекомендуется.
Лучше использовать его с фрагментами, основными преимуществами являются:
- Анимация в BottomNavigationView (без уродливой задержки в случае действий)
- Легко поддерживать состояние фрагментов.
- Гибкая backstack
Но если вы хотите придерживаться "Действия", то ответ @javaxian очень хорош, но мы можем его улучшить:
- Если в нашем файле макета нет BottomNavigation с правильным идентификатором, у нас будет исключение. Лучше иметь общий файл макета для действий с навигацией.
Решение:
1) Переименуйте BaseActivity в BaseNavigationActivity
2) Сделайте одиночный файл макета для всех ваших действий (например, activity_navigation.xml
) и явным образом вызовите в BaseNavigationActivity setContentView(R.layout.activity_navigation);
3) Удалите abstract int getContentViewId();
- Код в
selectBottomNavigationBarItem(int itemId)
является накладным, мы можем сделать это намного проще
Решение (в Котлине):
private fun selectBottomNavigationBarItem(itemId: Int) {
val menuItem = navigationView.menu.findItem(itemId)
menuItem.isChecked = true
}
Ответ 4
Вы можете использовать setSelectedItemId в каждом действии, когда оно начинается.
bottomNavigationView.setSelectedItemId(R.id.menu_item_id);
где R.id.menu_item_id находится в menu/navigate_items