如何在活动之间使用BottomNavigationView按下时突出显示项目?
我已为我的应用添加了底部导航视图,但我需要在活动之间而不是片段之间的底部导航视图,因此我已将此代码添加到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; } }); }}
xml对于3个活动是相同的:
您可以将BottomNavigationView与表示选项卡的活动一起使用。 关键是在每个活动中重复导航视图组件,并让每个活动的代码控制导航组件:在导航项目点击时启动正确的活动,并在活动开始后选择适当的导航项目。
您需要延迟启动新选择的活动(选项卡),以便在新活动替换上一个活动之前完成切换切换动画。
我的方法是让代表制表符的所有活动都从实现常见行为的同一BaseActivity类inheritance。
这是一个示例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
对于仍然在寻找这个问题的人来说,@ 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); }
你绝对可以将BottomNavigationView用于活动,但不建议这样做。 更好的是将它与Fragments一起使用,主要好处是:
- BottomNavigationView中的动画(活动时没有难看的延迟)
- 轻松维护碎片的状态
- 灵活的背板
但如果你想坚持使用活动,那么@javaxian的回答非常好,但我们可以改进它:
- 如果我们的布局文件没有具有正确id的BottomNavigation,那么我们将有exception。 更好的是为导航活动提供通用布局文件。
方案 :
1)将BaseActivity重命名为BaseNavigationActivity
2)为所有活动创建单个布局文件(例如activity_navigation.xml
),并在BaseNavigationActivity中显式调用setContentView(R.layout.activity_navigation);
3)删除abstract int getContentViewId();
-
selectBottomNavigationBarItem(int itemId)
代码是开销,我们可以做得更简单
解决方案 (在Kotlin中):
private fun selectBottomNavigationBarItem(itemId: Int) { val menuItem = navigationView.menu.findItem(itemId) menuItem.isChecked = true }