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

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")无法直接关联到音频文件,需调整数据结构和逻辑:

具体修正步骤

  1. 创建统一数据类
    将单词文本和对应音频资源ID绑定:
data class Vocabulary(
    val sourceWord: String,
    val targetWord: String,
    val audioResId: Int // 对应raw文件夹下的音频资源ID
)
  1. 重构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
    }
}
  1. 修正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)
        )
    }
}
  1. 修正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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:55:23