Search code examples
javaandroidandroid-recyclerviewtext-to-speech

Unable to Show imageView in recyclerVIew synchronously with TTS


How can i show/Hide imageView in recyclerView as TTS(text to speech) plays for all the available list items, one by one!

Activity method -This method is called r with Loop(not working, no bugs but simply do not give my expected output

    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 more understanding,

First, i displayed all items in recyclerView. Afterward, I am calling the displayed item in a method having for loop to TTS play each rows(list item). The problem i am facing now is the imageView is not displaying as each recyclerView item are being read by TTS.

Expected output is whenever TTS plays for each row item textView, An imageView(#image1) should show simultaneously




UPDATED TRIED 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++;
        }
    }
}

MyAdapter.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

  • You main fail is absence of listener for TTS. Without it you don't know when you should update your RecyclerView. Listener can 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 can be implemented. Here you can see how it works. Here is my github repository.