I have a RecyclerView
in which each item contains a button that plays sound from online url.
The problem is that I don't want the items to play sound at the same time and when you click on different sound, the previous one gets off but I don't know how can I do that ?
I would be appreciate if you could guide me through this problem
public class VersionAdapter3 extends RecyclerView.Adapter<VersionAdapter3.VersionViewholder> {
Context context;
List<Version3> versionsList;
final Mediaplayer mediaplayer=new Mediaplayer();
public VersionAdapter3(Context context, List<Version3> versionsList) {
this.context = context;
this.versionsList = versionsList;
}
@NonNull
@Override
public VersionViewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.raw3,parent,false);
return new VersionViewholder(view);
}
@Override
public void onBindViewHolder(@NonNull VersionViewholder holder, int position) {
Version3 version3 = versionsList.get(position);
holder.codeNameTxt.setText(version3.getCodeName());
holder.versionTxt.setText(version3.getVersion());
holder.descriptiontxt.setText(version3.getDescription());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(version3.getSong());
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.prepareAsync();
boolean isExpandable = versionsList.get(position).isExpandable();
holder.expandableLayout.setVisibility(isExpandable ? View.VISIBLE : View.GONE);
holder.btnplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mediaPlayer!=null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
version3.setIsplaying(false);
}
}
try {
if (holder.btnplay.getText().toString().equals("pause")) {
mediaPlayer.pause();
version3.setIsplaying(false);
holder.btnplay.setText("play");
}
else {
holder.btnplay.getText().toString().equals("play");
mediaPlayer.start();
holder.btnplay.setText("pause");
version3.setIsplaying(true);
}
} catch (Exception e) {
e.printStackTrace();
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
holder.btnplay.setText("play");
}
});
}
});
}
@Override
public int getItemCount() {
return versionsList.size();
}
public class VersionViewholder extends RecyclerView.ViewHolder {
TextView codeNameTxt, versionTxt, descriptiontxt;
LinearLayout linearLayout;
RelativeLayout expandableLayout;
Button btnplay;
public VersionViewholder(@NonNull View itemView) {
super(itemView);
codeNameTxt = itemView.findViewById(R.id.codename);
versionTxt = itemView.findViewById(R.id.version);
descriptiontxt = itemView.findViewById(R.id.description);
btnplay = itemView.findViewById(R.id.track_play);
linearLayout = itemView.findViewById(R.id.linear);
expandableLayout = itemView.findViewById(R.id.expandable);
linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Version3 version3 = versionsList.get(getAdapterPosition());
version3.setExpandable(!version3.isExpandable());
notifyItemChanged(getAdapterPosition());
}
});
}
}
}
when i click on the each item it get expanded and previous sound gets off but the button still shows in pause mode not play mode and I don't want the sound gets off when I expand a new item and I want that it gets off when I click on the next button just in a case that you pause previous button it works but I want automatically it gets off when I click new play button and the previous one gets completely off I would be so grateful if you could help me to fix my code and show me how can I edit it
CodePudding user response:
Here is an example:
The MainActivity class:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private VersionAdapter3 adapter;
private List<Version3> generateVersionList() {
List<Version3> versionsList = new ArrayList<>();
versionsList.add(new Version3("codeName 01", "version 01", "Description 01", "https://storage.googleapis.com/2waytech-apagar/Just a Miracle Apart - Lost European.mp3", Version3.State.STOPPED));
versionsList.add(new Version3("codeName 02", "version 02", "Description 02", "https://storage.googleapis.com/2waytech-apagar/Newspaper And Lace - Lost European.mp3", Version3.State.STOPPED));
versionsList.add(new Version3("codeName 03", "version 03", "Description 03", "https://storage.googleapis.com/2waytech-apagar/The Man in the House of Cards - Lost European.mp3", Version3.State.STOPPED));
return versionsList;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.list);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
adapter = new VersionAdapter3(generateVersionList());
recyclerView.setLayoutManager(llm);
recyclerView.setAdapter(adapter);
}
}
The VersionAdapter3 class:
public class VersionAdapter3 extends RecyclerView.Adapter<VersionAdapter3.VersionViewHolder> {
private final List<Version3> versionsList;
private final MediaPlayer mediaPlayer;
private Integer currentlyPlayingIndex = -1;
public VersionAdapter3(List<Version3> versionsList) {
this.versionsList = versionsList;
this.mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(mediaPlayer -> {});
}
private void setupMediaPlayer() {
mediaPlayer.setOnPreparedListener(MediaPlayer::start);
mediaPlayer.setAudioAttributes(
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
);
}
private void onPlayBtnTapped(int newIndex) {
if(newIndex != currentlyPlayingIndex && currentlyPlayingIndex != -1) {
versionsList.get(currentlyPlayingIndex).setState(Version3.State.STOPPED);
notifyItemChanged(currentlyPlayingIndex);
mediaPlayer.stop();
}
if(newIndex == currentlyPlayingIndex) {
if(mediaPlayer.isPlaying()) {
versionsList.get(newIndex).setState(Version3.State.PAUSED);
mediaPlayer.pause();
}
else {
versionsList.get(newIndex).setState(Version3.State.PLAYING);
mediaPlayer.start();
}
} else {
try {
currentlyPlayingIndex = newIndex;
Version3 version = versionsList.get(newIndex);
String dataSource = version.getSong();
version.setState(Version3.State.PLAYING);
mediaPlayer.reset();
mediaPlayer.setDataSource(dataSource);
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
notifyItemChanged(newIndex);
}
@Override
public void onViewAttachedToWindow(@NonNull VersionViewHolder holder) {
super.onViewAttachedToWindow(holder);
setupMediaPlayer();
}
@NonNull
@Override
public VersionViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.raw3, parent, false);
return new VersionViewHolder(view);
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull VersionViewHolder holder, int position) {
Version3 version3 = versionsList.get(position);
holder.codeNameTxt.setText(version3.getCodeName());
holder.versionTxt.setText(version3.getVersion());
holder.descriptiontxt.setText(version3.getDescription());
holder.adjustBtnTextByState(version3.getState());
holder.btnplay.setOnClickListener(view -> onPlayBtnTapped(position));
}
@Override
public int getItemCount() {
return versionsList.size();
}
public static class VersionViewHolder extends RecyclerView.ViewHolder {
TextView codeNameTxt, versionTxt, descriptiontxt;
Button btnplay;
public VersionViewHolder(@NonNull View itemView) {
super(itemView);
codeNameTxt = itemView.findViewById(R.id.codename);
versionTxt = itemView.findViewById(R.id.version);
descriptiontxt = itemView.findViewById(R.id.description);
btnplay = itemView.findViewById(R.id.track_play);
}
@SuppressLint("SetTextI18n")
public void adjustBtnTextByState(Version3.State state) {
switch (state) {
case STOPPED:
btnplay.setText("stopped");
break;
case PLAYING:
btnplay.setText("playing");
break;
case PAUSED:
btnplay.setText("paused");
break;
}
}
}
}
The Version3 class
public class Version3 {
private String codeName;
private String version;
private String description;
private String song;
private State state;
public Version3(String codeName, String version, String description, String song, State state) {
this.codeName = codeName;
this.version = version;
this.description = description;
this.song = song;
this.state = state;
}
public String getCodeName() {
return codeName;
}
public void setCodeName(String codeName) {
this.codeName = codeName;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSong() {
return song;
}
public void setSong(String song) {
this.song = song;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public enum State {
STOPPED, PLAYING, PAUSED
}
}
The main_activity.xml layout file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And the raw3.xml layout file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@ id/codename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="codename"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth="match_parent" />
<TextView
android:id="@ id/version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="version"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/codename"
app:layout_constraintWidth="match_parent" />
<TextView
android:id="@ id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="description"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/version"
app:layout_constraintWidth="match_parent" />
<Button
android:id="@ id/track_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/description" />
</androidx.constraintlayout.widget.ConstraintLayout>