[我正在尝试遵循:https://developer.android.com/guide/navigation/navigation-ui以及https://codelabs.developers.google.com/codelabs/android-navigation/#8的评论(尽管第二个链接在Kotlin中,并且我使用Javascript进行编码)以在Android中实现一个带有左侧导航栏的应用程序,右上角的设置按钮(首选项)。
我正在使用NavigationUI,其中包含抽屉和设置中每个选项的片段。
我的问题是我的设置片段没有出现。我想我快到了,但是尽管阅读了几篇文章,但问题仍然无法解决。
此代码允许我从导航抽屉中切换片段:
@Override
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);
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
//NavigationUI.setupWithNavController(toolbar, navController, mAppBarConfiguration);
}
如果我在最后两行切换注释的代码(因此我执行了最后一行,但没有倒数第二个,为了匹配该指南,则片段切换失败。
我处理“设置”菜单的代码是:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
/*
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
// TODO: Do something to accept settings
View contextView = findViewById(R.id.nav_host_fragment); // Apparently any layout can be used
Snackbar.make(contextView, "Settings", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
//changeFragment(new SettingsFragment());
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.nav_host_fragment, new SettingsFragment(), "nh")
.addToBackStack("nh")
.commit();
return true;
}
return super.onOptionsItemSelected(item);
*/
}
活动部分与上面的指南匹配,正在被调用(通过设置断点来证明),但无济于事。
如果我也将其切换为注释掉的代码,那么我的设置片段确实会出现,但会覆盖当前片段。我从另一个答案中了解到,这是因为我正在使用两种不同的方法来处理片段可见性,这很有意义,这就是为什么我试图让我的设置片段由NavigationUI框架处理。
我认为它必须非常简单才能治愈,但是已经阅读并重新阅读了指南(很多答案无法使它起作用)
您有不同的选择:
只需在导航图中定义SettingsFragment
:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--Your fragments-->
<!--Settings fragment-->
<fragment
android:id="@+id/settingsFragment"
android:name=".SettingsFragment"/>
</navigation>
然后在菜单上添加:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
在菜单中,使用图形中使用的相同ID:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/settingsFragment"
.../>
</menu>
最终覆盖onOptionsItemSelected
方法:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.onNavDestinationSelected(item, navController)
|| super.onOptionsItemSelected(item);
}
您也可以定义Global Action。
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--Global action-->
<action android:id="@+id/action_global_open_settings_fragment"
app:destination="@id/settingsFragment"/>
</navigation>
然后在您的代码中导航至目的地,只需使用:
Navigation.findNavController(view).navigate(R.id.action_global_open_settings_fragment);