TextToSpeech Inside Recyclerview Android Kotlin Example
Implement TextToSpeech inside a RecyclerView in Kotlin. Speak words out loud as users scroll through the list with easy-to-follow examples. | RRTutors
Android provided a library to speech the given text into voice. this library is called TextToSpeech library. This library can speak any word with provided locale.
To work with TextToSpeech library we need to create instance of it and pass required to text to it to speak-out.
Let's get started
Step 1: Create Simple Android Application
Step 2: To display list of items in application we will use Recyclerview widget. Let add Recyclerview inside activity_main.xml file
<?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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
|
Step 3:
Now let create an Adapter to bind the items to Recyclerview.
Adapters are used to bind the passed items to Listview. We have different types of adapters like
- ArrayAdapter
- BaseAdapter
- RecyclerviewAdapter
ArrayAdapter and BaseAdapter will use to bind the data to Listview. In this application we are taken Recyclerview so we will create RecyclerviewAdapter
Before create a Adapter class let create an Item layout to display the items. Our Item layout contains Imageview and Textview
Let our item xml file will be like below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:padding="8dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="48dp"
android:id="@+id/btnPlay"
android:layout_gravity="center"
android:src="@mipmap/ic_launcher"
android:layout_height="48dp"/>
<TextView
android:layout_width="wrap_content"
android:id="@+id/name"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:textStyle="bold"
android:layout_gravity="center"
android:layout_height="wrap_content"/>
</LinearLayout>
|
Let create a class which will extends RecyclerviewAdapter
package com.example.recyclverviewtts
import android.os.Build
import android.speech.tts.TextToSpeech
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ItemAdapter (private val tts: TextToSpeech): RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
var list: ArrayList<String> = ArrayList()
set(value) {
field = value
notifyDataSetChanged()
}
inner class ItemViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val name:TextView=itemView.findViewById(R.id.name)
val btnPlay:ImageView=itemView.findViewById(R.id.btnPlay)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_item_adapter, parent, false)
return ItemViewHolder(view)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
holder.name.text = list[position]
}
}
|
Step 4:
Now update our MainActivity to add adapter class to Recyclerview to bind the list of items
|
val recyclerView=findViewById<RecyclerView>(R.id.recyclerView) |
We will display list of fruits, so let create fruits list
|
arrayListOf( |
Now create TextToSpeech instance by
|
val tts = TextToSpeech(this) { |
here we passed locale as US English
Step 5:
Now pass this instance to our adapter class and add adapter to RecyclerView by adapter property
| val adapter = ItemAdapter(tts) recyclerView.adapter = adapter |
Inside Adapter class we have ImageView, onClick of ImageView we will pass the respected item text to TTS instance. Then it will speak out
|
btnPlay.setOnClickListener { |
Complete example code for TextToSpeech Inside Recyclerview
MainActivity
package com.example.recyclverviewtts
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.speech.tts.TextToSpeech
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.util.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView=findViewById<RecyclerView>(R.id.recyclerView)
val tts = TextToSpeech(this) {
Log.i("MainActivity", "onCreate: $it")
}
tts.language = Locale.US
val adapter = ItemAdapter(tts)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
adapter.list = arrayListOf(
"Apple",
"Avocados",
"Bananas",
"Blueberries",
"Cherries",
"Clementine",
"Cucumbers",
"Grapes",
"Guava",
"Mango",
"Orange",
"Pineapple"
)
}
}
|
ItemAdapter.kt
package com.example.recyclverviewtts
import android.os.Build
import android.speech.tts.TextToSpeech
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ItemAdapter (private val tts: TextToSpeech): RecyclerView.Adapter<ItemAdapter.ItemViewHolder>() {
var list: ArrayList<String> = ArrayList()
set(value) {
field = value
notifyDataSetChanged()
}
inner class ItemViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val name:TextView=itemView.findViewById(R.id.name)
val btnPlay:ImageView=itemView.findViewById(R.id.btnPlay)
init {
btnPlay.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tts.speak(list[adapterPosition], TextToSpeech.QUEUE_FLUSH, null, list[adapterPosition])
}
else {
tts.speak(list[adapterPosition], TextToSpeech.QUEUE_FLUSH, null)
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_item_adapter, parent, false)
return ItemViewHolder(view)
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
holder.name.text = list[position]
}
}
|