I have my adapters with image buttons and so. When pressing the sixth one it does as suppose to do. This is the last time it was updated correctly.
But then it keeps moving up the list doing the same thing. Now this
@Override
public void onClick(View view) {
TimeCard card = MyAdapter.cards.get(position);
switch (view.getId()) {
case R.id.playButton:
startTimer(card);
///new Logger(TimeCardButton.class).debug("Play button was pressed");
break;
case R.id.editButton:
Intent intent = new Intent(context, TimeCardAdd.class);
intent.putExtra("cardPosition", position);
context.startActivity(intent);
//TODO: Finish the editing so we can modify the timer card
Toast.makeText(context, "Edit button has been pressed.", Toast.LENGTH_SHORT).show();
break;
case R.id.stopButton:
stopTimer(card);
break;
case R.id.pauseButton:
pauseTimer(card);
break;
}
}
Is called only once. Which is correct. But this is called every second from the UI update call
private void sendPlayTimeButtons() {
cardButtons.get(TimeCardButtonId.PLAY_BUTTON.getId()).setVisibility(View.INVISIBLE);
cardButtons.get(TimeCardButtonId.EDIT_BUTTON.getId()).setVisibility(View.INVISIBLE);
cardButtons.get(TimeCardButtonId.PAUSE_BUTTON.getId()).setVisibility(View.VISIBLE);
cardButtons.get(TimeCardButtonId.STOP_BUTTON.getId()).setVisibility(View.VISIBLE);
// logger.debug("Sending Play Buttons");
}
Here's the code for my BindViewHolder
on the Adapter
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
//TODO: add everything back
holder.playButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
holder.editButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
holder.pauseButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
holder.stopButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
}
And last but finally the code for my ViewHolder
inside the adapter
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView timerTitle;
public TextView timeRemaining;
ImageButton playButton;
ImageButton editButton;
ImageButton pauseButton;
ImageButton stopButton;
LinkedList<ImageButton> buttons = new LinkedList<>();
public MyViewHolder(final View view) {
super(view);
timerTitle = view.findViewById(R.id.titleCardName);
timeRemaining = view.findViewById(R.id.timeLeftTextCard);
playButton = view.findViewById(R.id.playButton);
editButton = view.findViewById(R.id.editButton);
pauseButton = view.findViewById(R.id.pauseButton);
stopButton = view.findViewById(R.id.stopButton);
buttons.add(playButton);
buttons.add(editButton);
buttons.add(pauseButton);
buttons.add(stopButton);
}
}
Here's the startTimer
function which I have tested and it's called only once.
private void startTimer(TimeCard card) {
new Logger(TimeCardButton.class).debug("Play button was pressed");
if (!card.isTimeStarted()) {
card.setTimeStarted(true);
sendPlayTimeButtons();
logger.info("Starting Timer!");
} else if(card.isTimerPaused() && card.isTimeStarted()) {
TimerTask.notifyUpdate();
card.setTimerPaused(false);
sendPlayTimeButtons();
logger.info("Resuming from being paused!");
}
}
By all of them one at a time by my task system. My Task system only sends updates to the recycler from the activity handling the UI calls...
Again On those images, the buttons will move up the list every second having no reason. I tried replacing the button ids with tags. But that still failed.
You need to have a separate array in your adapter having the track of the list playing/paused/stopped. Let us consider the following.
0 -> Stopped
1 -> Playing
2 -> Paused
Now take an array in your adapter like the following.
// This initializes the array with the number of elements of your list
// and all initialized by 0 to indicate primarily all tracks were not playing.
int[] trackPlayer = new int[cards.size];
Now when you are clicking the buttons to do some action you need to update the array with the action as well.
@Override
public void onClick(View view) {
TimeCard card = MyAdapter.cards.get(position);
switch (view.getId()) {
case R.id.playButton:
startTimer(card);
trackPlayer[position] = 1; // Playing
break;
case R.id.editButton:
Intent intent = new Intent(context, TimeCardAdd.class);
intent.putExtra("cardPosition", position);
context.startActivity(intent);
//TODO: Finish the editing so we can modify the timer card
Toast.makeText(context, "Edit button has been pressed.", Toast.LENGTH_SHORT).show();
break;
case R.id.stopButton:
stopTimer(card);
trackPlayer[position] = 0; // Stopped
break;
case R.id.pauseButton:
pauseTimer(card);
trackPlayer[position] = 2; // Paused
break;
}
}
Now inside your onBindViewHolder
, you need to change the button's visibility based on the trackPlayer
values.
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.playButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
holder.editButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
holder.pauseButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
holder.stopButton.setOnClickListener(new TimeCardButton(context, holder.getAdapterPosition(), holder.buttons).checkStatus());
// Set the buttons visibility changes here.
if(playTrack[position] == 1) {
// Item in this position is being played
playButton.setVisibility(View.INVISIBLE);
editButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.VISIBLE);
stopButton.setVisibility(View.VISIBLE);
} else if(playTrack[position] == 0) {
// Item in this position is not being played/stopped
playButton.setVisibility(View.VISIBLE);
editButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
stopButton.setVisibility(View.INVISIBLE);
} else if(playTrack[position] == 2) {
// Item in this position is paused
playButton.setVisibility(View.VISIBLE);
editButton.setVisibility(View.INVISIBLE);
pauseButton.setVisibility(View.INVISIBLE);
stopButton.setVisibility(View.VISIBLE);
}
}
And remove the sendPlayTimeButtons
function call from your startTimer
function. I think you might consider removing the sendPlayTimeButtons
function as well.
private void startTimer(TimeCard card) {
new Logger(TimeCardButton.class).debug("Play button was pressed");
if (!card.isTimeStarted()) {
card.setTimeStarted(true);
notifyDataSetChanged(); // Call notifyDataSetChanged instead here.
} else if(card.isTimerPaused() && card.isTimeStarted()) {
TimerTask.notifyUpdate();
card.setTimerPaused(false);
notifyDataSetChanged(); // Call notifyDataSetChanged instead here.
}
}
Hope you get the idea.