Android:如何让设置菜单与NavigationUI一起出现?

Android:如何让设置菜单与NavigationUI一起出现?,android,android-fragments,preferences,android-architecture-navigation,android-jetpack-navigation,Android,Android Fragments,Preferences,Android Architecture Navigation,Android Jetpack Navigation,我试着遵循这一点:同时回顾一下(尽管第二个链接在Kotlin中,我正在用Javascript编写代码)在Android中实现一个应用程序,导航抽屉在左边,设置按钮(首选项)在右上角 我正在使用NavigationUI,其中包含抽屉和设置中每个选项的片段 我的问题是我的设置片段没有出现。我想我就快到了,但尽管看了几篇文章和几个问题,还是没能让它起作用 此代码允许我从导航抽屉切换片段: @Override protected void onCreate(Bundle savedInstanceSta

我试着遵循这一点:同时回顾一下(尽管第二个链接在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框架来处理我的设置片段


我觉得治疗起来一定很简单,但反复阅读指南(很多答案都无法解决问题)

你有不同的选择:

只需在导航图中定义
设置片段

<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>
在您的菜单中,使用图形中使用的相同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>

您还可以定义一个

我不确定我是否理解你的问题。但这是我的解决方案,我希望它能帮助你。 这是我的导航图

这就是代码。如您所见,我在设置片段中有一个动作:

    <fragment
    android:id="@+id/settingsFragment"
    android:name="packageName.SettingsFragment"
    android:label="Settings Fragment">
    <action
        android:id="@+id/actionSettingsToPassword"
        app:destination="@id/passwordDialogFragment"
        app:enterAnim="@anim/fragment_open_enter"
        app:exitAnim="@anim/fragment_open_exit" />
我不知道您是否知道如何在资源中添加preferences.xml。当然我也写了:

右键单击“res”New>Android资源目录

在资源类型字段中,选择XML。现在您将在“res”下有一个xml文件夹。再次:

右键单击“xml”New>xml文件

下面是我的“preferences.xml”:

这是我的应用课程:

class ForecastApplication : Application(){
override fun onCreate() {
    super.onCreate()
    PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
}
}
在应用程序的清单中,在应用程序标记内,定义已经创建的应用程序类

        android:name=".ForecastApplication"

我希望这就是您所需要的。

我所了解的是,您希望工具栏中有抽屉布局和菜单,对吗?您正在使用首选项设置从工具栏的菜单中输入的设置,对吗?但是你的设置没有显示。对吗?听起来不错-我可能有一些术语错了,因为这是我的第一个应用程序。我在吧台上有三块从左边进来的碎片(=抽屉布局?)。我有一个设置菜单(定义为公共类设置Fragment extends PreferenceFragmentCompat以及定义Seeting布局的关联XML文件)。我无法使用NavigationUI显示设置。请尝试在导航组件中添加设置片段或活动,然后在实现菜单的onClick之后,调用导航组件中已创建的导航。但把抽屉和菜单放在一起是不好的做法,其中一个是必要的。如果你设置抽屉和菜单,那会很烦人。你是不是建议我将设置菜单作为抽屉中的另一个片段添加?我想你可能在看我手机上的一些应用程序,它们有一个或另一个。不,不。你的设置不能在你的抽屉里。看,背景是一个新片段。因此,您应该从当前片段导航到设置片段。对于此操作,正如您所说,您正在使用导航组件,因此您应该在导航组件中实现设置片段,然后在菜单选项或抽屉菜单中,当您单击设置时,你应该从当前片段到设置调用导航操作。我想我已经实现了你的选项1,但例外是我在两个位置使用了不同(但相同)的@+id/settingsFragment名称,我没有。我完全遵循了你的选项1,它可以工作。谢谢你帮我节省了几个小时的谷歌搜索时间。你的@layout/fragment\u设置与preferences.xml有什么关系?我认为我缺少@layout/fragment\u设置是关键,但与您一样,我有一个preferences.xml(在xml资源目录中),它定义了设置片段的视图。我也已经为您提供了我的设置片段。看看它。您还应该创建一个应用程序类,并将“PreferenceManager”设置为该类。我忘了向您提供该类,但我已经编辑了我的帖子,并向您展示了我的应用程序类。@PeteC my SettingFragment没有(@layout/fragment\u settings)。布局是(R.xml.preferences),请查看SettingsFragment的代码。要了解如何设置首选项,解决方案的第一部分(导航图的右下方)引用@layout/fragment\u settings,如下:。(很抱歉,布局没有在响应中保留格式)。我同意布局是在R.xml.preferences中设置的,这让我想知道@layout/fragment_设置包含什么内容(这可能正是我失败的原因)@PeteC ahh。是的,你说得对。这是我的错。我应该删除它:-)。我已经再次编辑了代码。忘了布局吧。您应该从XML的文件夹(例如R.XML.preferences)设置布局。这就是全部。只是别忘了导航和菜单中的ID应该是相同的。
Navigation.findNavController(view).navigate(R.id.action_global_open_settings_fragment);
    <fragment
    android:id="@+id/settingsFragment"
    android:name="packageName.SettingsFragment"
    android:label="Settings Fragment">
    <action
        android:id="@+id/actionSettingsToPassword"
        app:destination="@id/passwordDialogFragment"
        app:enterAnim="@anim/fragment_open_enter"
        app:exitAnim="@anim/fragment_open_exit" />
<item
    android:id="@+id/settingsFragment"
    android:icon="@drawable/ic_settings"
    android:title="Settings" />
    android:id="@+id/settingsFragment"
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Weather Location">
    <SwitchPreference
        android:defaultValue="true"
        android:disableDependentsState="true"
        android:key="USE_DEVICE_LOCATION"
        android:summary="Allow The App To Get Your Location"
        android:title="Use Device Location" />
    <EditTextPreference
        android:defaultValue="Tehran"
        android:dependency="USE_DEVICE_LOCATION"
        android:key="CUSTOM_LOCATION"
        android:summary="The Location For Which The Weather Is Displayed"
        android:title="Location" />
</PreferenceCategory>
<PreferenceCategory android:title="Units">
    <ListPreference
        android:defaultValue="METRIC"
        android:entries="@array/unitSystemEntries"
        android:key="UNIT_SYSTEM"
        android:summary="%s"
        android:title="Unit System"
        android:entryValues="@array/unitSystemValues"/>
</PreferenceCategory>
</PreferenceScreen>
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    addPreferencesFromResource(R.xml.preferences)
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    (activity as? AppCompatActivity)?.supportActionBar?.title = "Settings"
    (activity as? AppCompatActivity)?.supportActionBar?.subtitle = null
}
}
class ForecastApplication : Application(){
override fun onCreate() {
    super.onCreate()
    PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
}
}
        android:name=".ForecastApplication"