notifyItemChanged() 在 setOnUtteranceProgressListener 中调用时不起作用

Dan*_*ray 5 java android kotlin android-recyclerview

编辑

我创建了一个演示项目来Github展示确切的问题。吉特项目


我写了一个可扩展recyclerViewKotlin每一行都有一个播放按钮,它使用TextToSpeech. 播放按钮的文本应在播放时更改为停止,然后在播放结束时更改回播放。

当我调用notifyItemChangedinsideonStartonDoneof 时setOnUtteranceProgressListeneronBindViewHolder不会调用并且 recyclerView 中的行将不再正确展开和折叠。

t1 = TextToSpeech(context, TextToSpeech.OnInitListener { status ->
    if (status != TextToSpeech.ERROR) {
        t1?.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
            override fun onStart(utteranceId: String?) {
                recyclerView.adapter.notifyItemChanged(position)
            }

            override fun onStop(utteranceId: String?, interrupted: Boolean) {
                    super.onStop(utteranceId, interrupted)
                    onDone(utteranceId)
            }

            override fun onDone(utteranceId: String?) {
                val temp = position
                position = -1
                recyclerView.adapter.notifyItemChanged(temp)
            }

            override fun onError(utteranceId: String?) {}
//                    override fun onError(utteranceId: String?, errorCode: Int) {
//                        super.onError(utteranceId, errorCode)
//                    }
        })
    }
})
Run Code Online (Sandbox Code Playgroud)

onBindViewHolder:

override fun onBindViewHolder(holder: RabbanaDuasViewHolder, position: Int){
    if (Values.playingPos == position) {
        holder.cmdPlay.text = context.getString(R.string.stop_icon)
    }
    else {
        holder.cmdPlay.text = context.getString(R.string.play_icon)
    }
}
Run Code Online (Sandbox Code Playgroud)

我如何notifyItemChanged(position)从内部调用setOnUtteranceProgressListener或我可以使用什么回调,以便 notifyItemChanged 仅在可以安全执行时执行?

Bir*_*ani 6

我试图复制您的问题,但我知道它不起作用,因为UtteranceProgressListener主线程上未调用 的onBindViewHolder方法,这就是未调用适配器的方法的原因。

这对我有用,也应该对你有用:

使用runOnUiThread{}方法来执行这样的操作RecyclerView

t1.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
    override fun onError(utteranceId: String?) {
    }

    override fun onStart(utteranceId: String?) {
        runOnUiThread {
            recyclerView.adapter?.notifyItemChanged(position)
        }
    }

    override fun onStop(utteranceId: String?, interrupted: Boolean) {
        super.onStop(utteranceId, interrupted)
        onDone(utteranceId)
    }

    override fun onDone(utteranceId: String?) {
        val temp = position
        position = -1
        runOnUiThread {
            recyclerView.adapter?.notifyItemChanged(temp)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)