javaandroidandroid-recyclerviewandroid-viewholder

How to detect each RecyclerView item after it is displayed


I want to detect each item in my RecylerView after it is displayed to the user.

Basically, I am trying to play a sound on each item after it is loaded on the screen.

But I am not able to detect whenever each item is loaded on the screen! Is there any method I have to call to detect each item rendered

E.g 1st RecyclerView item displayed -> play sound
    2st RecyclerView item displayed -> play sound...

My Adapter class looks like this -

public class AdapterListAnimation extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Multiples> items = new ArrayList<>();

    private Context ctx;
    private OnItemClickListener mOnItemClickListener;
    private int animation_type = 0;
    .........
    .........

I am calling this initComponent() method from onCreated() method. Can you give advice on what should I do to achieve my goal as described above?

private void initComponent() {
    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);
    items = DataGenerator.getPeopleData(this,of,value);
    setAdapter();

    /* MediaPlayer mp=MediaPlayer.create(this, R.raw.sword);
    if (mp.isPlaying()) {
        mp.stop();
        mp.release();
        mp = MediaPlayer.create(this, R.raw.sword);
    } mp.start();*/
}

private void setAdapter() {
    // Set data and list adapter
    mAdapter = new AdapterListAnimation(this, items, animation_type);
    recyclerView.setAdapter(mAdapter);

    // on item list clicked
    mAdapter.setOnItemClickListener(new AdapterListAnimation.OnItemClickListener() {
        @Override
        public void onItemClick(View view, com.math.multiplication.model.Multiples obj, int position) {
            Snackbar.make(parent_view, "Item " + obj.first + " clicked", Snackbar.LENGTH_SHORT).show();
        }
    });
}

Solution

  • You need to add listener for TTS. Then update your RecyclerView to show right image when speech starts and ends.

    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.

    Here is main part of my MainActivity class.

    private void initTts() {
        tts = new TextToSpeech(this, this);
        tts.setLanguage(Locale.US);
        tts.setOnUtteranceProgressListener(new MyListener());
    }
    
    @Override
    public void onInit(int status) {
        playSound(0);
    }
    
    private void playSound(int index) {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.valueOf(index));
        tts.speak(data.get(index), TextToSpeech.QUEUE_ADD, hashMap);
    }
    
    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) {
        }
    }