Как выделить элемент при нажатии, используя 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();

  1. Код в 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