Невозможно отобразить imageView в утилите-регенераторе синхронно с TTS - PullRequest
3 голосов
/ 04 апреля 2019

Как я могу показать / скрыть imageView в recyclerView при воспроизведении TTS (текст в речь) для всех доступных элементов списка, один за другим!

Метод действия -Этот метод вызывается с помощью цикла Loop (не работает, ошибок нет, но просто не дает ожидаемого результата

    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 воспроизводил все строки (элемент списка). Проблема, с которой я сейчас сталкиваюсь, заключается вimageView не отображается, поскольку каждый элемент recyclerView читается TTS.

Ожидаемый вывод - всякий раз, когда 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++;
        }
    }
}

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

Ответы [ 3 ]

4 голосов
/ 09 апреля 2019

Ваш главный недостаток - отсутствие слушателя 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) {
        }
    }

Я создал тестовый проект, чтобы показать, как его можно реализовать. Здесь вы можете увидеть, как это работает. Здесь - мой github-репозиторий.

0 голосов
/ 09 апреля 2019

Пожалуйста, проверьте это.В вашем коде вы пропустили UtteranceProgressListener.Вы должны добавить UtteranceProgressListener, который даст вам события слушателя завершения речи.Кроме того, вам понадобится utteranceID, который будет передан tts.speak(), который поможет вам определить речь, если вам это нужно.Возьмите переменную как

String utterId = "";

, затем в вашем TextToSpeech onInit перед вызовом convertTextToSpeech зарегистрируйте этого слушателя в своих 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 передается на convertTextToSpeech, поскольку это первый вызов.Здесь я внес некоторые изменения в convertTextToSpeech.В этом я удалил цикл, который вы использовали ранее вместо этого, это будет рекурсивная функция.

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

    }

Как вы можете видеть, tts.speak() устарел, вы должны использовать новый, чтобы избежать проблемв последней версии Android.

В вашем MyAdapter вы должны установить предыдущий элемент image_show в false.

public void updateItem(Multiples newItem, int pos) {
    if (pos > 0) {
        items.get(pos - 1).setImage_show(false);
    }
    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());

    notifyDataSetChanged();
}

Проверьте загруженный GIF.Пожалуйста, держите нас в курсе.

enter image description here

Если вам нужна помощь, вы можете попросить.Спасибо

0 голосов
/ 05 апреля 2019

Вставьте приведенный ниже фрагмент кода в Adapter в 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();
        }

Пусть это поможет Спасибо.

...