我已经使用Android Studio项目模板创建了Navigation Drawer Activity,并以编程方式添加了一些菜单项,并将选定的侦听器项设置为导航到目标片段。
这里,我想做的是单击上面添加的每个菜单项应打开相同的目标片段说HomeFragment 但具有不同的参数,以便我可以重新使用布局。
到目前为止,只有一个问题,即菜单项未正确突出显示,并且始终检查了Home项,这非常有用。我认为这是因为我已将self链接添加到home片段。有什么办法可以解决这个问题?
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navController = Navigation.findNavController(this, R.id.nav_host_fragment);
// Adding menu items
Menu menu = navigationView.getMenu();
SubMenu labels = menu.addSubMenu("Labels");
labels.add(R.id.group_labels, 201, 201, "Label 1").setIcon(R.drawable.ic_menu_gallery);
labels.add(R.id.group_labels, 202, 202, "Label 2").setIcon(R.drawable.ic_menu_gallery);
navigationView.invalidate();
appBarConfig = new AppBarConfiguration.Builder(R.id.home)
.setDrawerLayout(drawer)
.build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfig);
NavigationUI.setupWithNavController(navigationView, navController);
// Navigation item click listener
navigationView.setNavigationItemSelectedListener(item -> {
if (item.getGroupId() == R.id.group_labels) {
HomeFragmentDirections.ActionHomeSelf action = HomeFragmentDirections.actionHomeSelf();
action.setLabel(item.getTitle().toString());
navController.navigate(action);
}
navigationView.setCheckedItem(item.getItemId()); // Not working
NavigationUI.onNavDestinationSelected(item, navController);
drawer.closeDrawer(GravityCompat.START);
return true;
});
}
mobile_navigation.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/home">
<fragment
android:id="@+id/home"
android:label="@string/menu_home"
android:name=".fragments.HomeFragment"
tools:layout="@layout/fragment_home">
<argument
android:name="label"
app:argType="string"
android:defaultValue="default label" />
<action
android:id="@+id/action_home_self"
app:destination="@id/home"
app:launchSingleTop="false">
</action>
<action
android:id="@+id/action_home_to_blank"
app:destination="@id/blankFragment" />
</fragment>
<fragment
android:id="@+id/blankFragment"
android:name=".BlankFragment"
android:label="fragment_blank"
tools:layout="@layout/fragment_blank" />
</navigation>
activity_main_drawer.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/home"
android:icon="@drawable/ic_menu_camera"
android:orderInCategory="0"
android:title="@string/menu_home" />
<item
android:id="@+id/blankFragment"
android:icon="@drawable/ic_menu_camera"
android:orderInCategory="0"
android:title="@string/hello_blank_fragment" />
</group>
<item
android:orderInCategory="200"
android:title="@string/drawer_menu_group_labels">
<menu>
<group
android:id="@+id/group_labels"
android:checkableBehavior="single" />
</menu>
</item>
<item
android:orderInCategory="300"
android:title="@string/drawer_menu_group_pages">
<menu>
<group
android:id="@+id/group_pages"
android:checkableBehavior="single" />
</menu>
</item>
</menu>
我对此问题的猜测(我认为这不是您的错,而是Android API的缺陷)是NavigationUI自动设置已检查的项目AFTER onNavigationItemSelected
,基于MenuItem的先前状态。因此,您在.setCheckedItem
中的onNavigationItemSelected
将被覆盖,但无效...
对于这个问题,我的解决方法是使用Thread
和sleep
像打击一样产生时间滞后:
private static final long NAVIGATION_ITEM_SET_DELAY = 500L; // milliseconds
navigationView.setNavigationItemSelectedListener(item -> {
(...)
new Thread(() -> {
try {
Thread.sleep(NAVIGATION_ITEM_SET_DELAY);
runOnUiThread(() -> navigationView.setCheckedItem(item.getItemId()));
} catch (InterruptedException e) {
Log.e(LOG_TAG, "An InterruptedException caught", e);
}
}).start();
(...)
});