Android RecyclerView数据传详情页时遇参数缺失异常求助
问题:传递数据到DetailFragment时触发"data参数缺失"异常
异常信息:
java.lang.IllegalArgumentException: Required argument "data" is missing and does not have an android:defaultValue at com.project.icacraft.ui.detail.DetailFragmentArgs$Companion.fromBundle(DetailFragmentArgs.kt:60) at com.project.icacraft.ui.detail.DetailFragment.onActivityCreated(DetailFragment.kt:35)
问题根源分析
- 导航图初始化顺序冲突:DetailActivity布局中通过
app:navGraph提前指定了导航图,NavController会在Activity启动时自动加载导航图并初始化DetailFragment。后续调用navController.setGraph传递参数时,Fragment已完成初始化,参数无法同步到实例中。 - 空安全处理漏洞:DetailActivity中使用
intent.extras?.let { ... },若Intent无额外数据,参数传递逻辑完全不执行,导致DetailFragment无参数可用。 - Navigation参数生成不一致:尽管导航图中设置了
app:nullable="true",但Navigation组件生成的DetailFragmentArgs代码未正确识别该配置,仍将参数视为必填项。
解决方案
方案1:调整NavController初始化逻辑,确保参数传递到起始Fragment
修改DetailActivity的初始化流程,避免布局提前加载导航图,改为代码手动初始化并传递参数:
步骤1:修改activity_detail.xml布局
移除navHostFragment的app:navGraph属性:
<fragment android:id="@+id/detailHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:name="androidx.navigation.fragment.NavHostFragment" app:defaultNavHost="true" />
步骤2:修改DetailActivity代码
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_detail) val navHostFragment = supportFragmentManager.findFragmentById(R.id.detailHostFragment) as NavHostFragment val navController = navHostFragment.navController // 强制校验数据非空,避免无参数跳转 val data = intent.getParcelableExtra<Data>("data") ?: run { Toast.makeText(this, "数据异常", Toast.LENGTH_SHORT).show() finish() return } // 构建参数Bundle并初始化导航图 val argsBundle = Bundle().apply { putParcelable("data", data) } navController.setGraph(R.navigation.nav_detail, argsBundle) }
方案2:修复跳转时的空安全校验
在所有跳转DetailActivity的位置,确保数据非空再发起跳转:
HomeFragment中修改onClick:
override fun onClick(v: View?, data: Data) { data?.let { val intent = Intent(activity, DetailActivity::class.java) intent.putExtra("data", it) startActivity(intent) } ?: run { Toast.makeText(activity, "数据异常,无法跳转", Toast.LENGTH_SHORT).show() } }
HomeNewCraftFragment中修改onClick:
override fun onClick(v: View?, data: Data) { data?.let { val intent = Intent(activity, DetailActivity::class.java) intent.putExtra("data", it) startActivity(intent) } ?: run { Toast.makeText(activity, "数据异常,无法跳转", Toast.LENGTH_SHORT).show() } }
方案3:同步Navigation参数生成代码
执行Build > Rebuild Project重新构建项目,让Navigation组件根据导航图的app:nullable="true"重新生成DetailFragmentArgs代码,同时在DetailFragment中处理参数为空的情况:
override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) (activity as DetailActivity?)!!.toolbarDetail() val args = DetailFragmentArgs.fromBundle(requireArguments()) args.data?.let { initView(it) } ?: run { // 参数为空时返回上一页 activity?.finish() Toast.makeText(context, "数据加载失败", Toast.LENGTH_SHORT).show() } }
内容的提问来源于stack exchange,提问作者Alfian Yuda Pratama
相关产品推荐
相关产品推荐

