使用导航组件导航到首选项片段
Navigating to preference fragment using navigation component
我正在尝试将我的中型应用程序迁移到新的 Android navigation
组件。
目前,我的应用程序由 single activity
组成,我打算保持不变(就此而言);所以,我面临这个问题,我有一个设置片段 (PreferenceFragment
),基本上可以从其他所有片段导航到该片段。
此导航是通过应用栏中的菜单进行的,因此 onOptionsItemSelected
(包含此导航)位于主 activity.
中
我无法确定将 settingsFragment
连接到其他设备的正确方法。
将它与所有其他人联系起来对我来说就像意大利面条一样。
应该settingsFragment
连接到所有其他片段吗?
我是否应该放弃单一的 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
回调。
我正在尝试将我的中型应用程序迁移到新的 Android navigation
组件。
目前,我的应用程序由 single activity
组成,我打算保持不变(就此而言);所以,我面临这个问题,我有一个设置片段 (PreferenceFragment
),基本上可以从其他所有片段导航到该片段。
此导航是通过应用栏中的菜单进行的,因此 onOptionsItemSelected
(包含此导航)位于主 activity.
我无法确定将 settingsFragment
连接到其他设备的正确方法。
将它与所有其他人联系起来对我来说就像意大利面条一样。
应该
settingsFragment
连接到所有其他片段吗?我是否应该放弃单一的 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
回调。