在我的应用程序中,我有一个OptionsMenu,许多Fragment都使用它。因此,我创建了以下BaseFragment:
abstract class BaseFragment : Fragment() {
private lateinit var navController: NavController
protected fun askForPermissions(permissionRequestCode: Int, vararg permissions: String) {
requestPermissions(permissions, permissionRequestCode)
}
protected fun checkPermission(permission: String, activity: Activity): Boolean = when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> true // It is not needed at all as there were no runtime permissions yet
else -> ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
inflater!!.inflate(R.menu.menu_topbar, menu)
@SuppressLint("RestrictedApi")
if (menu is MenuBuilder) {
menu.setOptionalIconsVisible(true)
}
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
navController = Navigation.findNavController(view!!)
return when (item.itemId) {
R.id.menu_topbar_profile -> {
navController.navigate(actionBaseToProfile())
true
}
R.id.menu_topbar_favorites -> {
navController.navigate(actionBaseToFavorites())
true
}
R.id.menu_topbar_help -> {
navController.navigate(actionBaseToHelp())
true
}
else -> false
}
}
}
然后在导航文件中添加了BaseFragment和目标Fragments。这是一个片段:
<fragment
android:id="@+id/fragment_base"
android:name="com.test.scanner.base.BaseFragment">
<action
android:id="@+id/action_base_to_profile"
app:destination="@id/fragment_profile" />
</fragment>
<fragment
android:id="@+id/fragment_profile"
android:name="com.test.scanner.ui.profile.ProfileFragment"
tools:layout="@layout/fragment_profile" />
如您所见,我没有为BaseFragment定义布局,因为没有人。如果我想通过单击OptionsMenu的某个元素导航到特定屏幕(例如ProfileFragment),则始终会收到IllegalArgumentException。例外:
java.lang.IllegalArgumentException: navigation destination com.test.scanner.debug:id/action_base_to_profile is unknown to this NavController
我们如何在BaseFragment中使用导航组件。这种情况是否有可能解决?或者有其他解决方案?
答案 0 :(得分:3)
您正在混合事物。不要将abstract
类放入导航图,而只能将扩展此BaseFragment类的类放入您的案例中。我建议您从本教程navigation-architecture-components开始,一旦完成,请尝试阅读有关抽象类的更多信息,然后从本文简化解决方案。完成后,尝试添加菜单,但不要将其放入baseFragment中,而是将不同的菜单放入每个片段中,而对下一个片段仅执行一个操作即可。这样会更容易。将头缠好后,添加按钮之类的新内容。
答案 1 :(得分:1)
如果在项目中使用SaveArgs,请从“ BaseFragment”导航到其他(不是Abstract)片段,请执行以下步骤:
1)在您的navigation.xml中为“ 导航”标签添加“ android:id ”:
<action
android:id="@+id/itemContent"
app:destination="@id/destination_item_content" />
2)在“导航”标签内添加不带“片段”的“ 动作”:
val direction = MobileNavigationDirections.itemContent()
findNavController().navigate(direction)
3)重建项目
4)使用刚刚生成的类“ MobileNavigation”。该名称来自您的“导航”标签的ID。
$(this).attr('data-action', 'add-to-cart');
请在此处阅读其他信息:Use Safe Args with a global action
答案 2 :(得分:0)
这似乎是该问题的一个很好的解决方案(并且对我有用):
public class MyFragmentFactory extends FragmentFactory{
@NonNull
@Override
public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
if (className.equalsIgnoreCase("com.proj.MyBaseFragment")){
return MyFragmentFactory.getMyFragment();
}else {
return super.instantiate(classLoader, className);
}
}
}
在您的活动 onCreated 方法中,输入以下内容
getSupportFragmentManager().setFragmentFactory(new MyFragmentFactory());
基本上,您与 fargement 管理器一起工作,但会接管某些片段的实例化,这些片段只有您知道要根据运行时情况创建。