在活动之间使用BottomNavigationView按下时如何突出显示项目?

时间:2017-01-19 14:27:11

标签: java navigation uinavigationbar bottomnavigationview android-bottomnav

我已为我的应用添加了底部导航视图,但我需要在活动之间而不是片段之间的底部导航视图,因此我已将此代码添加到Java以用于我的所有3个活动。

当我在手机中选择“秒”或“第三”时,所有内容都是正确的,但问题是突出显示第一项。

我需要突出显示我按下的项目。

我已经使用了片段并且它运行良好但我仍然是使用片段的初学者所以我正在使用活动。

第一个活动代码是:

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


}}

3个活动的xml相同:

<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>

4 个答案:

答案 0 :(得分:15)

您可以将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 Studio的底部导航活动模板的完整示例:

https://github.com/ddekanski/BottomNavigationViewBetweenActivities

答案 1 :(得分:6)

对于仍然在寻找这个问题的人来说,@ 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);
}

答案 2 :(得分:5)

你绝对可以将BottomNavigationView用于活动,但不建议这样做。 更好的是将其与Fragments一起使用,主要好处是:

  • BottomNavigationView中的动画(活动时没有难看的延迟)
  • 轻松维护碎片状态
  • 灵活的靠背

但如果你想坚持使用活动,那么@javaxian的答案非常好,但我们可以改进它:

  1. 如果我们的布局文件没有具有正确ID的BottomNavigation,那么我们将有异常。更好的是具有导航活动的通用布局文件。
  2. 解决方案

    1)将BaseActivity重命名为BaseNavigationActivity

    2)为您的所有活动制作单个布局文件(例如activity_navigation.xml),并在BaseNavigationActivity setContentView(R.layout.activity_navigation);中显式调用

    3)删除abstract int getContentViewId();

    1. selectBottomNavigationBarItem(int itemId)中的代码是开销,我们可以做得更简单
    2. 解决方案(在Kotlin中):

      private fun selectBottomNavigationBarItem(itemId: Int) {
          val menuItem = navigationView.menu.findItem(itemId)
          menuItem.isChecked = true
      }
      

答案 3 :(得分:1)

您可以在每个活动开始时在每个活动中使用 setSelectedItemId

$sql = "UPDATE users SET descriptionProfile='$prezentare', gender='$gender', locationUser='$localisation', userBirthday='$anniversaire' WHERE PlayerID='$pr'";

其中 R.id.menu_item_id 位于菜单/ navigate_items