Andorid RecyclerView适配器ImageButton问题

时间:2019-03-03 22:15:42

标签: java android android-recyclerview onclicklistener android-imagebutton

所以我有image buttons的适配器,依此类推。当按第六个时,它会按预期执行。这是最后一次正确更新。

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

仅被调用一次。哪个是对的。但这是从UI更新调用中每秒调用的一次

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

在我的任务系统中,一次全部将其选中。我的任务系统仅将处理UI调用的活动中的更新发送给回收商...

再次在这些图像上,这些按钮将每秒无理由地在列表中向上移动。我尝试用标签替换按钮ID。但这仍然失败。

1 个答案:

答案 0 :(得分:0)

您需要在适配器中拥有一个单独的阵列,以播放/暂停/停止列表的曲目。让我们考虑以下内容。

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

希望您能明白。