Android RecyclerView跳转新Activity时Intent传值失败问题解决
问题原因
传值失败是两个代码逻辑错误导致的:
- 列表项点击事件里给Intent传入的所有参数都是
getItemId(position)的返回值,该方法重写后返回的是列表位置的Long类型数字,根本不是商品标题、编码、价格这类实际业务数据 - 目标Activity里用
getStringExtra()读取Long类型参数,数据类型完全不匹配,自然无法获取有效值
另外代码还存在冗余导入、列表刷新通知位置计算越界的小问题,可一并修正。
修正后的代码实现
1. 适配器ItemViewAdapter.kt修正
删除无用的java.security.AccessController.getContext导入,修正点击传参逻辑,推荐直接序列化传递整个商品对象,避免逐个写字段出错,同时修复分页插入的通知逻辑:
package com.example.app.adapter import android.content.Context import android.content.Intent import android.view.LayoutInflater import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.example.app.R import com.example.app.models.products.Results import com.example.app.ui.home.DescriptionActivity import java.io.Serializable // 注意:给你的Results数据类加上Serializable接口实现,格式示例:data class Results(xxx字段): Serializable class ItemViewAdapter(private val context: Context) : RecyclerView.Adapter<ItemViewAdapter.MyViewHolder>() { private var itemList: MutableList<Results> = mutableListOf() private var page: Int = 0 fun setListItem(item: List<Results>) { val oldSize = itemList.size itemList.addAll(item) // 修复原notify位置计算错误,避免数组越界 notifyItemRangeInserted(oldSize, item.size) page++ } class MyViewHolder(view: android.view.View) : RecyclerView.ViewHolder(view) { private val title = view.findViewById<TextView>(R.id.tvTitle) private val code = view.findViewById<TextView>(R.id.tvNumber) private val quantity = view.findViewById<TextView>(R.id.tvQuantity) private val price = view.findViewById<TextView>(R.id.tvPrice) private val available = view.findViewById<TextView>(R.id.tvAvailable) private val category = view.findViewById<TextView>(R.id.tvCategory) fun bind(item: Results) { title.text = item.name code.text = item.code.toString() quantity.text = item.quantities[0].quantity.toString() price.text = item.prices[0].price.toString() available.text = item.active.toString() category.text = item.category?.name } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false) return MyViewHolder(v) } override fun getItemCount(): Int { return itemList.size } override fun getItemId(position: Int): Long { return position.toLong() } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val data = itemList[position] holder.bind(data) holder.itemView.setOnClickListener { val intent = Intent(context, DescriptionActivity::class.java) // 直接传递整个商品对象,无需逐个拼接字段,降低写错概率 intent.putExtra("product_data", data) context.startActivity(intent) } } }
2. 目标Activity DescriptionActivity.kt修正
直接读取传递过来的完整商品对象赋值,无需逐个读取零散字段:
package com.example.app.ui.home import android.graphics.Color import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View import android.view.WindowInsetsController import android.view.WindowManager import com.example.app.R import com.example.app.databinding.ActivityDescriptionBinding import com.example.app.models.products.Results @Suppress("DEPRECATION") class DescriptionActivity : AppCompatActivity() { private lateinit var binding: ActivityDescriptionBinding override fun onCreate(savedInstanceState: Bundle?) { window.apply { clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN statusBarColor = Color.TRANSPARENT if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { this@DescriptionActivity.window.decorView.windowInsetsController ?.setSystemBarsAppearance( 0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS ) } } } super.onCreate(savedInstanceState) binding = ActivityDescriptionBinding.inflate(layoutInflater) val view = binding.root setContentView(view) getItemIntent() } private fun getItemIntent(){ // 兼容不同Android版本读取序列化对象 val product = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getSerializableExtra("product_data", Results::class.java) } else { @Suppress("DEPRECATION") intent.getSerializableExtra("product_data") as? Results } product?.let { setData(it) } } private fun setData(product: Results) { binding.tvTitle.text = product.name binding.tvCode.text = product.code.toString() binding.tvCategory.text = product.category?.name // 此处替换为你Results模型中实际的商品描述字段即可 binding.tvDescription.text = product.description ?: "" binding.tvPrice.text = product.prices[0].price.toString() binding.tvQuantity.text = product.quantities[0].quantity.toString() } }
API对接场景参考实践
- 列表跳转详情优先传递序列化后的完整数据模型,不要零散传递单个字段,减少参数名写错、类型不匹配的问题
- 如果商品模型字段非常多,不推荐直接用Intent序列化传参,可以只传递商品ID,进入详情页后再根据ID请求完整的商品详情接口,避免Intent传参大小超限
- RecyclerView分页加载调用
notifyItemRangeInserted时,参数固定为「当前列表原有长度、本次新增数据条数」,不要手动计算分页偏移,避免出现数据越界、列表动画错乱问题
内容的提问来源于stack exchange,提问作者SaeedMoeen
相关产品推荐
相关产品推荐

