1

I have below adapter for RecyclerView.
There are particular sounds associated to each RecyclerView item as you can see.
How to make the item click wait until the related sound finishes playing?
Currently, when RecyclerView item is clicked, it immediately jumps to intended activity without waiting for the sound to finish playing.

So, it should be line this:
1. User clicks on RecyclerView item.
2. Related sound starts playing.
3. Sound finishes playing.
4. A new activity starts.

Adapter

public class RvAdapter extends RecyclerView.Adapter<RvAdapter.ViewHolder> {
    RecyclerView.Adapter.StateRestorationPolicy PREVENT_WHEN_EMPTY;
    private String[] titles = {"Topic1","Topic2","Topic3","Topic4","Topic5","Topic6","Topic7","Topic8","Topic9","Topic10"};
    private ArrayList<Item> items;
    private Context context;
    public RvAdapter(ArrayList<Item> items, Context context) { this.items = items; this.context = context; }
    MediaPlayer main_mp;

    @NonNull
    @Override
    public RvAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent,false);
        return new ViewHolder(view); }

    @Override
    public void onBindViewHolder(@NonNull RvAdapter.ViewHolder holder, final int position) {
        releaseMediaPlayer();
        final Item item = items.get(position);
        holder.imageView.setImageResource(item.getImageResource());
        holder.textView.setText(titles[position]);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) { releaseMediaPlayer();
                Context context = RvAdapter.this.context;
                final Intent intent;
                switch (position){
                    case 0: setupMediaPlayer(R.raw.topic1sound); intent = new Intent(context, Topic1.class); break;
                    case 1: setupMediaPlayer(R.raw.topic2sound); intent = new Intent(context, Topic2.class); break;
                    case 2: setupMediaPlayer(R.raw.topic3sound); intent = new Intent(context, Topic3.class); break;
                    case 3: setupMediaPlayer(R.raw.topic4sound); intent = new Intent(context, Topic4.class); break;
                    case 4: setupMediaPlayer(R.raw.topic5sound); intent = new Intent(context, Topic5.class); break;
                    case 5: setupMediaPlayer(R.raw.topic6sound); intent = new Intent(context, Topic6.class); break;
                    case 6: setupMediaPlayer(R.raw.topic7sound); intent = new Intent(context, Topic7.class); break;
                    case 7: setupMediaPlayer(R.raw.topic8sound); intent = new Intent(context, Topic8.class); break;
                    case 8: setupMediaPlayer(R.raw.topic9sound); intent = new Intent(context, Topic9.class); break;
                    case 9: setupMediaPlayer(R.raw.topic10sound); intent = new Intent(context, Topic10.class); break;
                    default: throw new IllegalStateException("Unexpected value: " + position);
                } context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() { return items.size(); }
    public void setupMediaPlayer(int resource) {main_mp = MediaPlayer.create(context, resource); main_mp.start();}
    public void releaseMediaPlayer(){if (main_mp != null) { main_mp.stop(); main_mp.release(); main_mp = null; }}

    public static class ViewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView textView;
        public ViewHolder(@NonNull final View itemView) { super(itemView);
            imageView = itemView.findViewById(R.id.titleImageView);
            textView = itemView.findViewById(R.id.titleTextView); }
    }
}

2 Answers2

0

Not really tested but, you can try adding a callback when the sound stops playing, like this:

public void setupMediaPlayer(int resource, Class<? extends Activity> activityClass) {
        main_mp = MediaPlayer.create(context, resource);
        main_mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                context.startActivity(new Intent(context, activityClass));
            }
        });
        main_mp.start();
    }
Luciano Ferruzzi
  • 1,042
  • 9
  • 20
  • Thank you for the effort. However, it didn't help. You have mentioned `MainAcivity.class` in the `OnCompletionListener()` but I don't want it to redirect the RecyclerView items' click to a `MainAcivity.class` everytime. Additionally, the next activity didn't wait for the playing sound to finish. – Suman Chhetri Aug 02 '20 at 18:18
  • I edited the method to accept an Activity as parameter as well. Strange that it didn't work the docs of the "setOnCompletionListener" states the following: "Register a callback to be invoked when the end of a media source has been reached during playback." – Luciano Ferruzzi Aug 02 '20 at 18:32
0

I did a little different than what @Luciano suggested and my issue is now resolved.
I added OnCompletionListener() on each Switch case like below.

case 0: setupMediaPlayer(R.raw.Topic1);
    main_mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) { Intent intent = new Intent(context,Topic1.class); context.startActivity(intent); }
    });
break;