Android RecyclerView Адаптер ImageButton Проблема - PullRequest
0 голосов
/ 04 марта 2019

У меня есть адаптеры с кнопками изображений и т. Д.При нажатии на шестой он делает как положено делать.Это последний раз, когда он обновлялся правильно.

enter image description here

Но затем он продолжает перемещаться вверх по списку, делая то же самое.Теперь этот

enter image description here

@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;
    }
}

вызывается только один раз.Что правильно.Но это вызывается каждую секунду из вызова обновления пользовательского интерфейса

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");
}

Вот код моего BindViewHolder на адаптере

@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());
}

И, наконец, наконец-то код моего ViewHolder внутри адаптера

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);
    }
}

Вот функция startTimer, которую я протестировал, и она вызывается только один раз.

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!");
    }
}

Все они по одному в моей системе задач,Моя система задач только отправляет обновления в утилизатор из действия, обрабатывающего вызовы пользовательского интерфейса ...

Опять же На этих изображениях кнопки будут перемещаться вверх по списку каждую секунду без причины.Я попытался заменить идентификаторы кнопок с тегами.Но это все равно не удалось.

1 Ответ

0 голосов
/ 04 марта 2019

В вашем адаптере должен быть отдельный массив, в котором дорожка списка воспроизводится / останавливается / останавливается.Давайте рассмотрим следующее.

0 -> Stopped
1 -> Playing
2 -> Paused

Теперь возьмите массив в вашем адаптере, как показано ниже.

// 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]; 

Теперь, когда вы нажимаете кнопки, чтобы выполнить какое-либо действие, вам также необходимо обновить массив этим действием.

@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;
    }
}

Теперь внутри вашего onBindViewHolder вам нужно изменить видимость кнопки на основе значений trackPlayer.

@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);
    }
}

И удалите вызов функции sendPlayTimeButtons из вашей функции startTimer.Я думаю, вы могли бы также рассмотреть возможность удаления функции sendPlayTimeButtons.

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.
    }
}

Надеюсь, вы поняли идею.

...