使用导航组件导航到首选项片段

Navigating to preference fragment using navigation component

我正在尝试将我的中型应用程序迁移到新的 Android navigation 组件。

目前,我的应用程序由 single activity 组成,我打算保持不变(就此而言);所以,我面临这个问题,我有一个设置片段 (PreferenceFragment),基本上可以从其他所有片段导航到该片段。 此导航是通过应用栏中的菜单进行的,因此 onOptionsItemSelected(包含此导航)位于主 activity.

我无法确定将 settingsFragment 连接到其他设备的正确方法。 将它与所有其他人联系起来对我来说就像意大利面条一样。

  1. 应该settingsFragment连接到所有其他片段吗?

  2. 我是否应该放弃单一的 activity 应用程序架构,因为 Google 没有给出足够的理由(或任何理由)来支持它?

要处理您的问题,您可以使用global actions。 要使用它们,您需要在 <navigation> 标记内定义操作,而不是像通常那样在 <fragment> 内定义操作。 您的导航图将包含下一个代码

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

    <!--Your other fragments-->

    
    <!--Settings fragment-->
    <fragment
        android:id="@+id/settingsFragment"
        android:name="com.example.oleksii.Whosebug.SettingsFragment"/>

    <!--Global action-->
    <action android:id="@+id/open_settings_fragment"
        app:destination="@id/settingsFragment"/>
</navigation>

在图形编辑器中,它将以下一种方式显示(destination 左侧的箭头):

更多详情:https://developer.android.com/topic/libraries/architecture/navigation/navigation-global-action

但如果您的偏好是分层的,那么当您点击子偏好时,您会得到 Fragment <insert fragment name here> declared target fragment <guid> that does not belong to this FragmentManager!

我还没有找到解决办法。

要基于@Alexey 的回答,调用全局操作,您可以使用如下代码:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();
    if (id == R.id.action_settings) {
        Navigation.findNavController(this, R.id.nav_host_fragment).navigate(R.id.settingsFragment);
    }
    return super.onOptionsItemSelected(item);
}

我可以使用以下方法导航到另一个片段或偏好片段:

全局设置片段:

<PreferenceCategory
    app:title="@string/global_settings_header">
    <Preference
        app:key="fragment_a"
        app:title="A"
        app:fragment="....settings.SettingsFragmentA" />
    <Preference
        app:key="fragment_b"
        app:title="B"
        app:fragment=".....settings.SettingsFragmentB" />
</PreferenceCategory>

已在 activity 中实施 PreferenceFragmentCompat.OnPreferenceStartFragmentCallback

public class MainActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
....

@Override
public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
    NavController navController = Navigation.findNavController(MainActivity.this, R.id.nav_host_fragment);
    if (pref.getKey().equals("fragment_a")) {
        navController.navigate(R.id.nav_settings_fragment_a);
    } else if (pref.getKey().equals("fragment_b")) {
        navController.navigate(R.id.nav_settings_fragment_b);
    }
    return true;
}

....
}

我还可以使用 NavController 导航到导航图中定义的任何片段。

任何片段都可以在app:fragment=".....settings.SettingsFragment"中使用。这个想法是触发 onPreferenceStartFragment 回调。