Fragment中RecyclerView点击播放音频的MediaPlayer报错排查
问题描述
我正在开发一款应用,需要实现Fragment中RecyclerView的单词条目点击后播放对应音频,但编写点击逻辑时遇到问题,Adapter出现两个报错:
None of the following functions can be called with the arguments supplied.
create(Context!, Uri!) defined in android.media.MediaPlayer
create(Context!, Int) defined in android.media.MediaPlayer
2. `Unresolved reference: context` --- ## 相关代码 ### vocabularyAdapter ```kotlin class vocabularyAdapter(val sourceWord: Array<String>, val targetWord: Array<String> ) : RecyclerView.Adapter<vocabularyAdapter.MyViewHolder>() { class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvSourceWord = itemView.findViewById<TextView>(R.id.inEnglishOrFrench) val tvLingala = itemView.findViewById<TextView>(R.id.inLingala) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.vocabulary_item, parent, false) return MyViewHolder(itemView) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.tvSourceWord.text = sourceWord[position].toString() holder.tvLingala.text = targetWord[position] holder.itemView.setOnClickListener { val mediaPlayer = MediaPlayer.create(holder.context, targetWord[position]) mediaPlayer.start() } } override fun getItemCount(): Int { return sourceWord.size } }
VocabularyFragment
class VocabularyFragment : Fragment() { // TODO: Rename and change types of parameters private var param1: String? = null private var param2: String? = null private lateinit var adapter: vocabularyAdapter private lateinit var recyclerView: RecyclerView private lateinit var vocabularyArraylist: ArrayList<Vocabulary> lateinit var sourceWordid: Array<String> lateinit var lingalaid: Array<String> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { param1 = it.getString(ARG_PARAM1) param2 = it.getString(ARG_PARAM2) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_vocabulary, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) dataInitialize() val layoutManager = LinearLayoutManager(context) recyclerView = view.findViewById(R.id.vocabulary_recyclerview) recyclerView.layoutManager = layoutManager recyclerView.setHasFixedSize(true) adapter = vocabularyAdapter(sourceWordid, lingalaid) } private fun dataInitialize() { vocabularyArraylist = arrayListOf<Vocabulary>() sourceWordid = arrayOf("Apple", "Banana",) lingalaid = arrayOf("pomme", "banane") } }
vocabulary_item.XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="fragments.VocabularyFragment"> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/vocabulary_recyclerview" tools:listitem="@layout/vocabulary_item"/> </FrameLayout>
解决方案
错误1:Unresolved reference: context
ViewHolder本身没有context属性,需通过holder.itemView.context获取上下文对象。
错误2:MediaPlayer参数不匹配
MediaPlayer.create()只接受**资源ID(Int类型,如R.raw.apple)**或Uri对象作为音频源,你传入的单词字符串(如"pomme")无法直接关联到音频文件,需调整数据结构和逻辑:
具体修正步骤
- 创建统一数据类
将单词文本和对应音频资源ID绑定:
data class Vocabulary( val sourceWord: String, val targetWord: String, val audioResId: Int // 对应raw文件夹下的音频资源ID )
- 重构Adapter
- 接收
List<Vocabulary>作为数据源 - 点击事件中使用音频资源ID创建MediaPlayer
- 播放完成后释放资源避免内存泄漏
class VocabularyAdapter(val vocabList: List<Vocabulary>) : RecyclerView.Adapter<VocabularyAdapter.MyViewHolder>() { class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val tvSourceWord = itemView.findViewById<TextView>(R.id.inEnglishOrFrench) val tvLingala = itemView.findViewById<TextView>(R.id.inLingala) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layout.vocabulary_item, parent, false) return MyViewHolder(itemView) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val vocab = vocabList[position] holder.tvSourceWord.text = vocab.sourceWord holder.tvLingala.text = vocab.targetWord holder.itemView.setOnClickListener { val mediaPlayer = MediaPlayer.create(holder.itemView.context, vocab.audioResId) mediaPlayer.start() // 播放完成后释放资源 mediaPlayer.setOnCompletionListener { mp -> mp.release() } } } override fun getItemCount(): Int { return vocabList.size } }
- 修正Fragment逻辑
- 初始化包含音频ID的数据源
- 给RecyclerView设置Adapter(你之前遗漏了这一步)
class VocabularyFragment : Fragment() { // ... 其他代码不变 ... private lateinit var adapter: VocabularyAdapter private lateinit var vocabularyList: List<Vocabulary> override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) dataInitialize() val layoutManager = LinearLayoutManager(context) recyclerView = view.findViewById(R.id.vocabulary_recyclerview) recyclerView.layoutManager = layoutManager recyclerView.setHasFixedSize(true) adapter = VocabularyAdapter(vocabularyList) recyclerView.adapter = adapter // 补充设置Adapter } private fun dataInitialize() { vocabularyList = listOf( Vocabulary("Apple", "pomme", R.raw.apple), Vocabulary("Banana", "banane", R.raw.banana) ) } }
- 修正XML布局混淆问题
你提供的vocabulary_item.XML实际是Fragment的布局文件,真正的条目布局(vocabulary_item.xml)应包含两个TextView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:id="@+id/inEnglishOrFrench" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp"/> <TextView android:id="@+id/inLingala" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp" android:textColor="@android:color/darker_gray" android:layout_marginTop="4dp"/> </LinearLayout>
内容的提问来源于stack exchange,提问作者Mayamba Mwanza
相关产品推荐
相关产品推荐

