Java – Unable to synchronize with TTS to display imageView in recyclerVIew

Unable to synchronize with TTS to display imageView in recyclerVIew… here is a solution to the problem.

Unable to synchronize with TTS to display imageView in recyclerVIew

How do I show/hide imageView in RecyclerView because TTS (text to speech) plays all available list items one by one!

Activity method
– This method is called r with loop (not working, no errors, but not giving the output I expected at all

.)

    int position=0;
    public void convertTextToSpeech() {
        Multiples multiples1=items.get(position);
        for (Multiples item : items) {

text = item.first + "  " + item.getSecond() + " Za " + item.getResult() + ".";
            tts.speak(text, TextToSpeech.QUEUE_ADD, null);
            boolean speakingEnd = tts.isSpeaking();

if (speakingEnd) {
                Toast.makeText(getApplicationContext(), "Speaking...."+position, Toast.LENGTH_SHORT).show();
                multiples1.setImage_show(true);
                mAdapter.notifyItemChanged(position);
            } else {
                Toast.makeText(getApplicationContext(), "Done...."+position, Toast.LENGTH_SHORT).show();
            }
            position++;
        }
    }

The complete code is below for easy understanding

First, I display all the items in the recyclerView. After that, I call the displayed item in a method that has a for loop to play each row (list item) in TTS. The problem I’m facing now is that the imageView doesn’t show up because TTS is reading every recyclerView item.

The expected output is that imageView(#image1) should be displayed simultaneously whenever TTS plays for each line item textView




Updated attempt code

DisplayActivityResultAdapter.java

    ......
    .......
    int position = 0;
    public void convertTextToSpeech() {
        Multiples multiples1=items.get(position);
        for (Multiples item : items) {
            text = item.first + "  " + item.getSecond() + " Za " + item.getResult() + ".";
            tts.speak(text, TextToSpeech.QUEUE_ADD, null);
            boolean speakingEnd = tts.isSpeaking();

 Toast.makeText(getApplicationContext(), "Speaking...."+position, Toast.LENGTH_SHORT).show();
            multiples1.setImage_show(true);
              mAdapter.notifyItemChanged(position);
            Log.i("values","------------------------------------------Row value-"+item.getFirst()+" X "+item.getSecond()+", Position="+position);
             //------------------------
            MyAdapter m= (MyAdapter)  mAdapter;
            m.updateItem(item,position);
            position++;
        }
    }
}

My adapter .java

    .....
    .....
     Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
         - get element from your dataset at this position
         - replace the contents of the view with that element

if (holder instanceof MyAdapter.MyViewHolder) {
            final MyAdapter.MyViewHolder view = (MyAdapter.MyViewHolder) holder;
            Multiples p = items.get(position);
            view.name.setText(p.first + " X " + p.getSecond() + "= "+p.getResult());

if(position>0) {
                if (p.image_show) {
                    view.image1.setVisibility(View.VISIBLE);
                    view.image.setVisibility(View.INVISIBLE);
                } else {
                    view.image1.setVisibility(View.INVISIBLE);
                    view.image.setVisibility(View.VISIBLE);
                }
            }
        }
    }

public void updateItem(Multiples newItem, int pos) {
        Log.i("values","-----In updateItem Log----Row value-"+newItem.getFirst()+" X "+newItem.getSecond()+", Position="+pos);
        items.set(pos, newItem); update passed value in your adapter's data structure
        Log.e("msg","-----items.get(pos)------------->"+items.get(pos).getFirst()+" X " +items.get(pos).getSecond());

notifyItemChanged(pos,newItem);
    }

 Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return items.size();
    }
}

Solution

Your main failure is the lack of a TTS listener. Without it, you won’t know when you should update your RecyclerView.
The listener looks like this:

class MyListener extends UtteranceProgressListener {
        @Override
        public void onStart(String utteranceId) {
            int currentIndex = Integer.parseInt(utteranceId);
            mMainAdapter.setCurrentPosition(currentIndex);
            handler.post(new Runnable() {
                @Override
                public void run() {
                    mMainAdapter.notifyDataSetChanged();
                }
            });
        }

@Override
        public void onDone(String utteranceId) {
            int currentIndex = Integer.parseInt(utteranceId);
            mMainAdapter.setCurrentPosition(-1);
            handler.post(new Runnable() {
                @Override
                public void run() {
                    mMainAdapter.notifyDataSetChanged();
                }
            });
            if (currentIndex < data.size() - 1) {
                playSound(currentIndex + 1);
            }
        }

@Override
        public void onError(String utteranceId) {
        }
    }

I’ve created a test project to show how it works. Here you can see how it works. Here is my github repository.

Related Problems and Solutions