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

时间:2018-10-28 08:53:33

标签: android android-jetpack android-architecture-navigation

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

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

Navigation graph

我在确定将settingsFragment连接到其他方法的正确方法方面遇到麻烦。 对我来说,将其连接到所有其他对象似乎就像意大利面条。

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

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

4 个答案:

答案 0 :(得分:3)

我可以使用以下方法导航到另一个片段或首选项片段:

全局设置片段:

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

在活动中实施了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回调。

答案 1 :(得分:0)

要解决您的问题,可以使用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.stackoverflow.SettingsFragment"/>

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

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

enter image description here

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

答案 2 :(得分:0)

但是,如果您的首选项是分层的,则在单击子首选项时会得到Fragment <insert fragment name here> declared target fragment <guid> that does not belong to this FragmentManager!

我还没有找到解决方法。

答案 3 :(得分:0)

要基于@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);
}