【问题标题】:Android RecyclerView Adapter ImageButton ProblemAndroid RecyclerView Adapter ImageButton问题
【发布时间】:2019-03-03 22:15:42
【问题描述】:

我的适配器带有image buttons 等等。当按下第六个时,它会按预期进行。这是最后一次正确更新。

但它继续在列表中向上移动,做同样的事情。现在这个

@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。但这仍然失败。

【问题讨论】:

  • 嗨特里斯坦。这不是你应该提问的方式。提供示例代码,然后描述您的问题,以便有人可以帮助您。没有人能在另一边读心,如果你把问题抽象成现在这样,你会得到减分
  • 两张图片完全相同。
  • 你说得对,我现在没注意到更新
  • 很高兴看到startTimer函数的内容。
  • @KrystianG 我添加了方法

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


【解决方案1】:

您需要在适配器中有一个单独的数组,其中包含播放/暂停/停止列表的轨道。让我们考虑以下内容。

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

并从您的 startTimer 函数中删除 sendPlayTimeButtons 函数调用。我认为您也可以考虑删除 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.
    }
}

希望您能理解。

【讨论】:

  • 现在我觉得这么简单的解决方案很愚蠢,我忽略了谢谢
猜你喜欢
  • 2020-06-19
  • 2016-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多