如何使用Jetpack Navigation Component从Adapter向Fragment传递数据
1. 修改导航图添加参数配置
你需要先在nav_graph.xml的detailFragment节点下添加接收参数的声明,支持传递基础类型或者序列化的自定义对象:
<!-- 其余配置不变,仅修改detailFragment部分 --> <fragment android:id="@+id/detailFragment" android:name="com.example.studious.DetailFragment" android:label="fragment_detail" tools:layout="@layout/fragment_detail"> <!-- 可选方案1:传递整个User对象(要求User实现Parcelable/Serializable) --> <argument android:name="selected_user" app:argType="com.example.studious.User" /> <!-- 可选方案2:仅传递用户ID(后续可从数据库/接口再查详情) --> <!-- <argument android:name="user_id" app:argType="integer" android:defaultValue="-1" /> --> </fragment>
如果项目开启了Safe Args插件,会自动生成对应路由的参数类,后续传参更安全,推荐在模块级build.gradle中开启:
plugins { id 'com.android.application' id 'kotlin-android' id 'androidx.navigation.safeargs.kotlin' // 新增这行配置 }
2. 改造UserAdapter暴露点击事件
适配器中不要直接处理导航逻辑,将点击事件回调给外层的HomeFragment处理:
// 修改构造函数,新增点击回调参数 class UserAdapter( private val context: Context, private val userList:List<User>, private val onItemClick: (User) -> Unit // 点击事件回调 ): RecyclerView.Adapter<UserAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAdapter.ViewHolder { return ViewHolder(UserRowBinding.inflate(LayoutInflater.from(parent.context),parent,false)) } override fun onBindViewHolder(holder: UserAdapter.ViewHolder, position: Int) { val model = userList[position] holder.binding.name.text = model.name holder.binding.city.text = model.city holder.binding.email.text = model.email // 点击时触发回调 holder.binding.layout.setOnClickListener { onItemClick(model) } } override fun getItemCount(): Int = userList.size class ViewHolder(val binding:UserRowBinding): RecyclerView.ViewHolder(binding.root) }
3. HomeFragment中执行导航传参
在HomeFragment初始化适配器时,实现点击回调,调用Navigation组件完成跳转和传参:
// HomeFragment中初始化Adapter的代码示例 private fun initUserList() { val userAdapter = UserAdapter( context = requireContext(), userList = yourUserList, // 替换为你的用户列表数据源 onItemClick = { selectedUser -> // 方式1:使用Safe Args传参(推荐,类型安全) val direction = HomeFragmentDirections.actionHomeFragmentToDetailFragment(selectedUser) findNavController().navigate(direction) // 方式2:不使用Safe Args,手动构造Bundle传参 /* val bundle = bundleOf( "selected_user" to selectedUser // 传ID的话就写 "user_id" to selectedUser.id ) findNavController().navigate(R.id.action_homeFragment_to_detailFragment, bundle) */ } ) binding.userRecyclerView.adapter = userAdapter }
4. DetailFragment中获取参数并渲染UI
在DetailFragment的生命周期方法中取出传递的参数,绑定到对应UI控件:
class DetailFragment : Fragment() { // 方式1:使用Safe Args获取参数 private val args: DetailFragmentArgs by navArgs() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val selectedUser = args.selectedUser // 把用户数据绑定到UI binding.nameTv.text = selectedUser.name binding.cityTv.text = selectedUser.city binding.emailTv.text = selectedUser.email // 方式2:手动从Arguments取参数 /* val selectedUser = arguments?.getParcelable<User>("selected_user") // 取ID的话就写 val userId = arguments?.getInt("user_id", -1) selectedUser?.let { // 绑定UI逻辑 } */ } }
注意事项
如果选择传递整个User对象,需要确保User类实现Parcelable接口,Android Studio可通过Parcelable插件一键生成实现代码,性能优于Serializable。
内容的提问来源于stack exchange,提问作者Digvijay Singh Thakur
相关产品推荐
相关产品推荐

