Kotlin中RecyclerView点击触发Toast报错问题求助
RecyclerView条目点击弹出Toast报错解决方案
问题描述
使用Kotlin开发时,想要实现RecyclerView条目点击弹出Toast消息,但触发了如下报错:
None of the following functions can be called with the arguments supplied: public open fun makeText(p0: Context!, p1: CharSequence!, p2: Int): Toast! defined in android.widget.Toast public open fun makeText(p0: Context!, p1: Int, p2: Int): Toast! defined in android.widget.Toast
相关代码
PrintActivity.kt
package com.questionbank class PrintActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val vBinding = ActivityPrintBinding.inflate(layoutInflater) setContentView(vBinding.root) val helper = SqliteHelper(this, "myDB.sql", 1) var recyclerViewAdapter = CustomAdapter() recyclerViewAdapter.listData = helper.select() vBinding.myRecyclerView.adapter = recyclerViewAdapter vBinding.myRecyclerView.layoutManager = LinearLayoutManager(this) vBinding.myRecyclerView.addItemDecoration( DividerItemDecoration(this, DividerItemDecoration.VERTICAL) ) } class CustomAdapter : RecyclerView.Adapter<CustomAdapter.Holder>() { var listData = ArrayList<questionType>() inner class Holder(val vBinding: QuestionLayoutRecyclerBinding) : RecyclerView.ViewHolder(vBinding.root) { fun setData(id:Int?, question: String, answer: String, exp: String) { vBinding.printId.text=id.toString() vBinding.myLinear.setOnClickListener { // error occur Toast.makeText(this@PrintActivity, "test", Toast.LENGTH_SHORT).show() } } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder { val vBinding = QuestionLayoutRecyclerBinding.inflate( LayoutInflater.from(parent.context), parent, false ) return Holder(vBinding) } override fun onBindViewHolder(holder: Holder, position: Int) { val question = listData[position] holder.setData(question.id, question.question, question.answer, question.exp) } override fun getItemCount(): Int { return listData.size } } }
activity_print.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".PrintActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/myRecyclerView" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="32dp" android:layout_marginTop="32dp" android:layout_marginEnd="32dp" android:layout_marginBottom="32dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
question_layout_recycler.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/myLinear" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="10dp"> <TextView android:id="@+id/printId" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" /> </LinearLayout>
解决方案
报错原因是Toast.makeText的Context参数引用错误——你在Holder的点击事件中使用this@PrintActivity,但Holder是CustomAdapter的内部类,CustomAdapter又嵌套在PrintActivity中,这种多层嵌套的this引用无法正确指向有效的Context。
提供两种可行的解决方法:
方法一:从View获取Context(推荐)
直接借助ViewHolder中绑定的View获取Context,代码简洁且无需额外传递参数:
vBinding.myLinear.setOnClickListener { Toast.makeText(vBinding.root.context, "test", Toast.LENGTH_SHORT).show() }
每个View对象都持有自身关联的Context,用vBinding.root.context或者itemView.context都能正确获取到所需的Context。
方法二:给Adapter传递Context
在创建Adapter时传入Activity的Context,后续在Holder中使用该Context:
- 修改CustomAdapter的构造函数,添加Context参数:
class CustomAdapter(private val context: Context) : RecyclerView.Adapter<CustomAdapter.Holder>() { var listData = ArrayList<questionType>() inner class Holder(val vBinding: QuestionLayoutRecyclerBinding) : RecyclerView.ViewHolder(vBinding.root) { fun setData(id:Int?, question: String, answer: String, exp: String) { vBinding.printId.text=id.toString() vBinding.myLinear.setOnClickListener { Toast.makeText(context, "test", Toast.LENGTH_SHORT).show() } } } // 其余 onCreateViewHolder、onBindViewHolder、getItemCount 代码保持不变 }
- 在PrintActivity中创建Adapter时传入当前Context:
var recyclerViewAdapter = CustomAdapter(this)
内容的提问来源于stack exchange,提问作者조영민
相关产品推荐
相关产品推荐

