RecyclerView Adapter中用DataBinding实现点击跳转及planId传递的问题
解决DataBinding中RecyclerView Adapter点击事件报错与planId传递问题
首先说下你遇到的报错原因:DataBinding要求绑定的点击事件方法,要么和View.OnClickListener的onClick(View v)签名完全一致,要么通过lambda表达式来适配自定义的方法签名。你当前的onClick()方法没有参数,所以DataBinding找不到匹配的方法,才会抛出那个错误。
下面我一步步教你修改,同时实现传递planId的需求:
1. 调整XML布局的点击事件绑定
把原来的点击事件改成lambda表达式,直接把trainingPlanResponse里的planId作为参数传递给Adapter的方法:
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="trainingPlanResponse" type="xyz.TrainingPlanResponse" /> <variable name="presenter" type="xyz.MyPlansAdapter"/> </data> <TextView android:id="@+id/tvPlan" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/ic_launcher" android:drawableRight="@drawable/arrow_right" android:layout_margin="@dimen/dp15" android:text="@{trainingPlanResponse.planName}" <!-- 用lambda传递planId给Adapter的点击方法 --> android:onClick="@{() -> presenter.onClick(trainingPlanResponse.planId)}" android:drawablePadding="@dimen/dp5" android:textSize="@dimen/sp18" android:textColor="@color/black_variant5" android:gravity="center_vertical" /> </layout>
如果你之后需要用到更多TrainingPlanResponse里的字段,也可以直接传递整个对象:android:onClick="@{() -> presenter.onClick(trainingPlanResponse)}"
2. 修改Adapter代码适配参数传递
第一种:接收planId参数
修改onClick方法的签名,添加planId参数,然后把它放到Intent里传递:
class MyPlansAdapter(private val context: Context?, private val list: ArrayList<TrainingPlanResponse>) : RecyclerView.Adapter<MyPlansAdapter.ViewHolder>() { override fun onBindViewHolder(holder: ViewHolder, position: Int) { val plan = list[position] // 简化绑定写法,比setVariable更直观 holder.binding.trainingPlanResponse = plan holder.binding.presenter = this // 立即执行绑定,确保数据及时刷新 holder.binding.executePendingBindings() } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val itemView = LayoutInflater.from(context).inflate(R.layout.item_myplans, parent, false) return ViewHolder(itemView) } override fun getItemCount(): Int = list.size // 修改方法签名,接收planId参数 fun onClick(planId: String?) { val intent = Intent(context, PlanWeekActivity::class.java) // 把planId存入Intent intent.putExtra("KEY_PLAN_ID", planId) context?.startActivity(intent) } // 优化ViewHolder,用具体的Binding类代替ViewDataBinding inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val binding: ItemMyplansBinding = DataBindingUtil.bind(itemView)!! } }
第二种:接收整个TrainingPlanResponse对象
如果选择传递整个对象,需要先让你的Model类实现Serializable(或者Parcelable,后者效率更高):
class TrainingPlanResponse : Serializable { var planId: String? = null var planName: String? = null }
然后修改Adapter的onClick方法:
fun onClick(plan: TrainingPlanResponse) { val intent = Intent(context, PlanWeekActivity::class.java) intent.putExtra("KEY_TRAINING_PLAN", plan) context?.startActivity(intent) }
3. 在PlanWeekActivity中接收参数
如果传递的是planId:
val planId = intent.getStringExtra("KEY_PLAN_ID")
如果传递的是整个对象:
val trainingPlan = intent.getSerializableExtra("KEY_TRAINING_PLAN") as TrainingPlanResponse
这样修改之后,不仅能解决点击事件的报错,还能顺利把planId传递到目标Activity啦。
内容的提问来源于stack exchange,提问作者varmashrivastava
相关产品推荐
相关产品推荐

