Java 无法在recyclerVIew中与TTS同步显示imageView

Java 无法在recyclerVIew中与TTS同步显示imageView,java,android,android-recyclerview,text-to-speech,Java,Android,Android Recyclerview,Text To Speech,当TTS(文本到语音)逐个播放所有可用列表项时,如何在recyclerView中显示/隐藏imageView 活动方法 -此方法称为r with Loop(不工作,没有bug,只是没有给出预期的输出) int position=0; public void convertTextToSpeech() { Multiples multiples1=items.get(position); for (Multiples item : items) {

当TTS(文本到语音)逐个播放所有可用列表项时,如何在recyclerView中显示/隐藏imageView

活动方法 -此方法称为r with Loop(不工作,没有bug,只是没有给出预期的输出)

    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++;
        }
    }
下面是完整的代码,以便于理解

首先,我在recyclerView中显示了所有项目。之后,我在一个方法中调用显示的项目,该方法必须让for循环TTS播放每行(列表项目)。我现在面临的问题是,当TTS读取每个recyclerView项目时,imageView没有显示

预期输出是每当TTS为每行项目textView播放时,一个imageView(#image1)应该同时显示




更新的试用代码 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++;
        }
    }
}
    .....
    .....
    // 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();
    }
}
MyAdapter.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++;
        }
    }
}
    .....
    .....
    // 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();
    }
}

将下面的代码片段放入
OnBindViewHolder中的
适配器中

        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();
        }

感谢您的帮助。

您的主要失败是缺少TTS的侦听器。没有它,您就不知道何时应该更新您的
RecyclerView
。 侦听器可以如下所示:

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) {
        }
    }
类MyListener扩展了OuttanceProgressListener{
@凌驾
public void onStart(字符串outtanceid){
int currentIndex=Integer.parseInt(outtanceId);
mMainAdapter.setCurrentPosition(currentIndex);
handler.post(新的Runnable(){
@凌驾
公开募捐{
mMainAdapter.notifyDataSetChanged();
}
});
}
@凌驾
公共无效onDone(字符串OUTTANCEID){
int currentIndex=Integer.parseInt(outtanceId);
mMainAdapter.setCurrentPosition(-1);
handler.post(新的Runnable(){
@凌驾
公开募捐{
mMainAdapter.notifyDataSetChanged();
}
});
if(currentIndex

我已经创建了一个测试项目来展示它是如何实现的。您可以看到它是如何工作的。这是我的github存储库。

请检查此项。在您的代码中,您被错过了
UtteranceProgressListener
。 您必须添加
outtanceprogresslistener
,它将为您提供语音完成侦听器事件。此外,您还需要outtanceid,它将被传递到
tts.speak()
,以帮助您在需要时识别语音。 以一个变量为例

String utterId = "";
然后在调用
convertexttospeech
之前,在您的
TextToSpeech
onInit
中,将此侦听器注册到您的tts

...
else{
 tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                                    @Override
                                    public void onStart(String utteranceId) {

                                    }

                                    @Override
                                    public void onDone(String utteranceId) {
                                        convertTextToSpeech(position);
                                    }

                                    @Override
                                    public void onError(String utteranceId) {

                                    }
                                });
                                convertTextToSpeech(0);
}
最初,0被传递给
convertexttospeech
,因为这是第一次调用。这里我对
convertexttospeech
做了一些更改。在这里,我删除了您之前使用的循环,它将是一个递归函数

 public void convertTextToSpeech(int pos) {
        if (pos >= items.size()) return;
        position = pos;
        final Multiples multiples = items.get(position);

        text = multiples.first + "  " + multiples.getSecond() + " Za " + multiples.getResult() + ".";

        utterId = (new Random().nextInt() % 9999999) + ""; // "" is String force

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Bundle params = new Bundle();
            params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utterId);

            tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, utterId);
        } else {
            HashMap<String, String> params = new HashMap<>();
            params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utterId);

            tts.speak(text, TextToSpeech.QUEUE_FLUSH, params);
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                MyAdapter m = (MyAdapter) mAdapter;
                multiples.setImage_show(true);
                m.updateItem(multiples, position);
                position++;
            }
        });

    }
检查上传的gif。请随时更新


如果您需要任何帮助,可以询问。谢谢

您的回收器适配器在哪里?通常,您的tts代码应该调用您的适配器来切换回收器项目的图像视图中的图像,并调用notifyItemChanged。@MDNaseemAshraf问题中提供了所有信息。请尝试发布答案或提供提示您是否使用git?您可以ovide链接到您的git存储库?@Monkey显示为您缺少图片
适配器:[![在此处输入图像描述][1][1]
@StackDanny该图像已过期。因此我将其删除。相反,我已在上述问题中添加了适配器代码。在adpter的onBindViewHolder方法中不允许写入tts!