Editar
Eu criei um projeto de demonstração em Github
mostrando o problema exato. Projeto Git .
Eu escrevi um expansível recyclerView
em Kotlin
cada linha tem um botão de play que usos TextToSpeech
. O texto do botão de jogo deve mudar para parar, enquanto o seu jogo, em seguida, mudar de volta para jogar quando ele terminar.
Quando eu chamo de notifyItemChanged
dentro onStart
e onDone
de setOnUtteranceProgressListener
, onBindViewHolder
não é chamado e as linhas no recyclerView deixará de expandir e recolher corretamente.
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)
// }
})
}
})
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)
}
}
Como posso chamar notifyItemChanged(position)
de dentro setOnUtteranceProgressListener
ou o que callback que posso usar para que notifyItemChanged executa somente quando é seguro para executar?
Eu tentei replicar o problema e eu vim a saber que ele não está funcionando porque os métodos de UtteranceProgressListener
não é chamado no thread principal e é por isso onBindViewHolder
método do adaptador não é chamado.
Isso funcionou para e deve funcionar para você também:
Use runOnUiThread{}
método para executar ações em RecyclerView
como este:
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)
}
}
}