You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jetpack Navigation Component从Adapter向Fragment传递数据

Jetpack Navigation Component 跨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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 17:27:04