使用导航组件导航到偏好设置片段

21

我正在尝试将我的中等规模的应用迁移到新的Android navigation组件。

目前,我的应用程序由single activity组成,并计划保持不变(因为这个原因);所以,我面临的问题是我有一个设置片段(PreferenceFragment),可以从任何其他片段导航到它。 通过应用栏中的菜单进行此导航,因此onOptionsItemSelected (包含此导航)在主活动中。

Navigation graph

我很难弄清楚连接settingsFragment与其他片段的正确方法。 将其连接到所有其他片段似乎对我来说就像意大利面条一样复杂。

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

  2. Google没有足够的理由(或任何理由)支持单个活动应用程序架构,我是否应该放弃它?

4个回答

38
为了解决你的问题,你可以使用{{全局操作}}。为了使用它们,你需要在<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


1
如果我有多个图表并需要使用全局操作,如何从其他片段访问它? - roghayeh hosseini
为什么我会收到一个错误信息:“ID在此Activity中没有引用View”? - IgorGanapolsky
OP的链接现在重定向到此处:https://developer.android.com/guide/navigation/navigation-global-action(将其粘贴以防旧链接有一天过期) - axby

6
我可以使用以下方法导航到另一个片段或偏好设置片段:
全局设置片段:
<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回调。

5

但如果您的偏好设置是分层的,当您点击子首选项时,您会收到 Fragment <insert fragment name here> declared target fragment <guid> that does not belong to this FragmentManager! 的错误信息。

我目前尚未找到解决方案。


1
你找到解决方案了吗? - Pav Sidhu
重写getCallbackFragment并实现onPreferenceStartFragmentCallback,在那里您必须使用navController启动自定义片段。 - Merthan Erdem
https://dev59.com/SLzpa4cB1Zd3GeqPOZ5C - Biscuit

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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接