Android Recyclerview MediaPlayer previous Item sound stop, release after new one is clicked

匿名 (未验证) 提交于 2019-12-03 02:54:01

问题:

In my app i have recyclerview items, and each item play sound when i click it. Problem is that when i click few items, they all play sounds in the same time until they finish. Lets say i click 10 items, all 10 play sounds in the same time and after some time app get crashed and i get this error: E/MediaPlayer: error (1, -19). I avoid app crashing by implementing automatic release with this code:

    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {                         @Override                         public void onCompletion(MediaPlayer mp) {                             mediaPlayer.release();                          }                     });

But that's not what i want, it is annoying to hear few sounds in the same time. What i want is to stop previous sound when i click new one, i try to implent mediaplayer stop and release, but without success.

This is the app in google play so you can check by yourself: https://play.google.com/store/apps/details?id=org.pero.androidd.animalSoundsQuiz

Here is my Adapter code where i play sounds. In this code there is part MediaPlayer.OnCompletionListener() where i release sound after sound finish to aviod E/MediaPlayer: error (1, -19) error, but that is not what i want in my app. I want to stop previous sound after i click new one.

import android.content.Context; import android.media.MediaPlayer; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView;  import com.bumptech.glide.Glide; import com.pero.androidd.animalsoundsforchildren.R;  import java.util.List;   public class ZivotinjeAdapter extends RecyclerView.Adapter<ZivotinjeAdapter.ViewHolder> {      private List<Zivotinje> mZivotinje;       @Override     public ZivotinjeAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {         Context context = parent.getContext();         LayoutInflater inflater = LayoutInflater.from(context);          // Inflate the custom layout         View contactView = inflater.inflate(R.layout.item_zivotinje, parent, false);          // Return a new holder instance         ViewHolder viewHolder = new ViewHolder(contactView);         return viewHolder;     }      @Override     public void onBindViewHolder(ZivotinjeAdapter.ViewHolder viewHolder, int position) {           Zivotinje zivotinjeIme = mZivotinje.get(position);          // Set item views based on the data model         TextView textView = viewHolder.nameTextView;         textView.setText(zivotinjeIme.getmAnimal_name());          //THIS IS WHERE I HANDALE IMAGE VIEW. Using glide for images         //Dohvacamo context svakog views         ImageView slika_source = viewHolder.imageView;         Glide.with(slika_source.getContext())                 .load((Integer) zivotinjeIme.getmAnimal_slika())                 .into(slika_source);           viewHolder.setItem(mZivotinje.get(position));      }       @Override     public int getItemCount() {         return mZivotinje.size();     }      public static class ViewHolder extends RecyclerView.ViewHolder {          public ImageView imageView;         public TextView nameTextView;         private Zivotinje mItem;            public void setItem(Zivotinje item) {             this.mItem = item;         }            public ViewHolder(final View itemView) {             super(itemView);              nameTextView = (TextView) itemView.findViewById(R.id.zivotinjaIme_id);             imageView = (ImageView) itemView.findViewById(R.id.slika_id);               //Handdaling clicks             itemView.setOnClickListener(new View.OnClickListener() {                 @Override                 public void onClick(View v) {                                                              final MediaPlayer mediaPlayer = MediaPlayer.create(v.getContext(), mItem.getmSound());                     mediaPlayer.start();                                           //releace media player after sound finish                     // BUT I DO NOT WANT TIS, I WANT TO STOP PREVIOUS SOUND WHEN I CLICK NEW ONE                     mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {                         @Override                         public void onCompletion(MediaPlayer mp) {                             mediaPlayer.release();                          }                     });                 }             });          }       }       public ZivotinjeAdapter(List<Zivotinje> animals) {         mZivotinje = animals;     }   }

EDIT EDIT EDIT EDIT EDIT EDIT:

I find solution, i do not know is this the smartest way to do it but it works for me fine:

What i done is that i made static media player variable and this way i can access to media player from ViewHolder and stop previous sound when i click new one. Hope it helps.

here is the whole code:

public class ZivotinjeAdapter extends RecyclerView.Adapter<ZivotinjeAdapter.ViewHolder> {      private static MediaPlayer mediaPlayer; //THIS IS THE CHANGE I DONE      @Override     public ZivotinjeAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {         Context context = parent.getContext();         LayoutInflater inflater = LayoutInflater.from(context);          // Inflate the custom layout         View contactView = inflater.inflate(R.layout.item_zivotinje, parent, false);          // Return a new holder instance         ViewHolder viewHolder = new ViewHolder(contactView);         return viewHolder;     }      @Override     public void onBindViewHolder(ZivotinjeAdapter.ViewHolder viewHolder, int position) {           Zivotinje zivotinjeIme = mZivotinje.get(position);          // Set item views based on the data model         TextView textView = viewHolder.nameTextView;         textView.setText(zivotinjeIme.getmAnimal_name());          //THIS IS WHERE I HANDALE IMAGE VIEW. Using glide for images         ImageView slika_source = viewHolder.imageView;         Glide.with(slika_source.getContext())                 .load((Integer) zivotinjeIme.getmAnimal_slika())                 .into(slika_source);           viewHolder.setItem(mZivotinje.get(position));      }       @Override     public int getItemCount() {         return mZivotinje.size();     }      public static class ViewHolder extends RecyclerView.ViewHolder {          public ImageView imageView;         public TextView nameTextView;         private Zivotinje mItem;           public void setItem(Zivotinje item) {             this.mItem = item;         }           public ViewHolder(final View itemView) {             super(itemView);              nameTextView = (TextView) itemView.findViewById(R.id.zivotinjaIme_id);             imageView = (ImageView) itemView.findViewById(R.id.slika_id);   //handaling clicks              itemView.setOnClickListener(new View.OnClickListener() {                 @Override                 public void onClick(View v) {                       if (mediaPlayer != null && mediaPlayer.isPlaying()) {                         mediaPlayer.stop();                         mediaPlayer.reset();                         mediaPlayer.release();                         mediaPlayer = null;                     }                       mediaPlayer = MediaPlayer.create(v.getContext(), mItem.getmSound());                     mediaPlayer.start();                  }             });          }       }      private List<Zivotinje> mZivotinje;      public ZivotinjeAdapter(List<Zivotinje> animals) {         mZivotinje = animals;     }   }

回答1:

You first have to check if there is a sound that is already playing and if there is, you should stop it when the user decides to start a new sound.

itemView.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 if (mediaplayer.isPlaying ()) {                     if (mediaplayer != null){                         mediaplayer.stop ();                     }                 } else {                     if (mediaplayer != null) {                         mediaplayer.start ();                     }                 }             }         });

In setOnCompletionListner you release the sound if the user listens to the whole sound clip.

        mediaplayer. setOnCompletionListner (new MediaPlayer.OnCompletionListner () {             public void OnCompletion (MediaPlayer mediaplayer) {                 mediaplayer.release ();             }         });


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!