如何在嵌套Fragment场景中使用Navigation(NavHost)实现RecyclerView点击跳转
问题解决方案
1. RecyclerView 点击跳转Navigation实现
你有两种可选实现方式,推荐第二种解耦写法:
方式1:直接利用内部类特性跳转
因为你的TransformAdapter是TransformFragment的嵌套内部类,可以直接访问外部Fragment的findNavController()方法,无需传入NavHost ID查找,直接在点击事件处填入代码即可:
holder.itemView.setOnClickListener { findNavController().navigate(R.id.nav_detail) }
注意:该方式仅适用于Adapter为Fragment内部类的场景,存在潜在的内存泄漏风险,更推荐使用回调方式。
方式2:通过点击回调实现(规范写法)
步骤1:给Adapter添加点击回调构造参数
修改TransformAdapter的构造方法,传入点击事件回调:
class TransformAdapter(val onItemClick: (text: String, position: Int) -> Unit) : ListAdapter<String, TransformViewHolder>(/* 原有DiffUtil逻辑不变 */) {
步骤2:在条目点击处触发回调
修改onBindViewHolder中的点击逻辑:
override fun onBindViewHolder(holder: TransformViewHolder, position: Int) { // 原有绑定逻辑不变 holder.itemView.setOnClickListener { val currentText = getItem(position) onItemClick(currentText, holder.bindingAdapterPosition) } }
步骤3:在Fragment中初始化Adapter时处理跳转
val adapter = TransformAdapter { text, position -> // 跳转时可携带参数给Fragment2 val args = bundleOf( "content_text" to text, "item_position" to position ) findNavController().navigate(R.id.nav_detail, args) } recyclerView.adapter = adapter
2. FrameLayout作为NavHost容器报错原因及解决方案
报错原因
app:navGraph、app:defaultNavHost是NavHostFragment的专属属性,普通FrameLayout无法识别这些属性,也不会自动实例化NavHostFragment组件,你直接给FrameLayout加这些属性自然会报错。
正确动态使用FrameLayout承载NavHost的方法
步骤1:修改XML布局
移除FrameLayout上的Navigation专属属性:
<FrameLayout android:id="@+id/nav_host_fragment_content_main" android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginLeft="@dimen/fragment_horizontal_margin" android:layout_marginRight="@dimen/fragment_horizontal_margin" android:layout_weight="1" />
步骤2:在宿主Activity中手动初始化NavHostFragment
在Activity的onCreate方法中添加如下代码:
if (supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main) == null) { // 创建NavHostFragment实例,传入导航图 val navHostFragment = NavHostFragment.create(R.navigation.mobile_navigation) supportFragmentManager.beginTransaction() .replace(R.id.nav_host_fragment_content_main, navHostFragment) // 等价于app:defaultNavHost="true",支持返回键处理 .setPrimaryNavigationFragment(navHostFragment) .commit() }
配置完成后即可正常使用FrameLayout作为NavHost的容器。
内容的提问来源于stack exchange,提问作者engmms
相关产品推荐
相关产品推荐

