TextToSpeech Inside Recyclerview Android Kotlin Example

Published July 16, 2022

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.

TextToSpeech Inside recyclerview android Example

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)
 recyclerView.layoutManager = LinearLayoutManager(this)

 

We will display list of fruits, so let create fruits list

arrayListOf(
            "Apple",
            "Avocados",
            "Bananas",
            "Blueberries",
            "Cherries",
            "Clementine",
            "Cucumbers",
            "Grapes",
            "Guava",
            "Mango",
            "Orange",
            "Pineapple"
        )

 

Now create TextToSpeech instance by

 val tts = TextToSpeech(this) {
          
        }
tts.language = Locale.US

 

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 {
                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)
                }
            }
            

 

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]
    }
}

 

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

216 Views