Android 在回收器视图中同时结束的多个倒计时

Android 在回收器视图中同时结束的多个倒计时,android,listview,android-recyclerview,runnable,countdowntimer,Android,Listview,Android Recyclerview,Runnable,Countdowntimer,我有一个回收者视图,其中每个项目都有一个倒计时计时器,并且可能有多个倒计时计时器同时结束。我想做的是在计时器结束时删除项目。如果只有一个项目,那么代码工作绝对正常,但当有多个项目时,它会崩溃,出现indexoutofbounds异常。我尝试了stack overflow上提到的不同解决方案,但它们似乎都不能帮助我删除视图 这是我的适配器代码 public class UpcomingContestRecyclerAdapter extends RecyclerView.Adapter<Up

我有一个回收者视图,其中每个项目都有一个倒计时计时器,并且可能有多个倒计时计时器同时结束。我想做的是在计时器结束时删除项目。如果只有一个项目,那么代码工作绝对正常,但当有多个项目时,它会崩溃,出现indexoutofbounds异常。我尝试了stack overflow上提到的不同解决方案,但它们似乎都不能帮助我删除视图

这是我的适配器代码

public class UpcomingContestRecyclerAdapter extends RecyclerView.Adapter<UpcomingContestRecyclerAdapter.ViewHolder> {

private Context context;
private ArrayList<LiveAndUpcomingContest> live_and_upcoming_contest;
private Activity activity;

//Constructor
public UpcomingContestRecyclerAdapter(Activity context, ArrayList<LiveAndUpcomingContest> live_and_upcoming_contest) {
    // TODO Auto-generated constructor stub
    this.context = context;
    this.live_and_upcoming_contest = live_and_upcoming_contest;
    this.activity = context;
}


@Override
public UpcomingContestRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.upcoming_contests_list_item, viewGroup, false);
    return new ViewHolder(view);
}

// Initialize the viewholder class.
public class ViewHolder extends RecyclerView.ViewHolder{
    CountDownTimer timer;
    private TextView game_countdown;

 public ViewHolder(View view) {
        super(view);
        game_countdown = view.findViewById(R.id.game_countdown);
}
}

@Override
public void onBindViewHolder(final UpcomingContestRecyclerAdapter.ViewHolder viewHolder, final int position) {

    if(viewHolder.timer!= null)
    {
        viewHolder.timer.cancel();

    }
    //Start countdown timer on the game countdown view.
    viewHolder.timer = new CountDownTimer(live_and_upcoming_contest.get(position).getStart_time(), 500) {
        public void onTick(long millisUntilFinished) {
            long secondsInMilli = 1000;
            long minutesInMilli = secondsInMilli * 60;
            long hoursInMilli = minutesInMilli * 60;

            long elapsedHours = millisUntilFinished / hoursInMilli;
            millisUntilFinished = millisUntilFinished % hoursInMilli;

            long elapsedMinutes = millisUntilFinished / minutesInMilli;
            millisUntilFinished = millisUntilFinished % minutesInMilli;

            long elapsedSeconds = millisUntilFinished / secondsInMilli;

            String yy = String.format("%02d:%02d:%02d", elapsedHours, elapsedMinutes, elapsedSeconds);
            viewHolder.game_countdown.setText(yy);
        }

        public void onFinish() {
            viewHolder.game_countdown.setText("00:00:00");
            live_and_upcoming_contest.remove(position);
            notifyDataSetChanged();
        }
    }.start();
}
公共类UpComingChallectRecyclerAdapter扩展了RecyclerView.Adapter{
私人语境;
私人ArrayList直播和即将到来的比赛;
私人活动;
//建造师
公共升级竞赛回收器适配器(活动上下文、阵列列表直播和即将到来的竞赛){
//TODO自动生成的构造函数存根
this.context=上下文;
this.live_and_coming_contest=live_and_coming_contest;
这个活动=上下文;
}
@凌驾
public upComingChallengerAdapter.ViewHolder onCreateViewHolder(ViewGroup ViewGroup,int i){
View View=LayoutInflater.from(viewGroup.getContext()).flate(R.layout.uncoming_竞赛_列表_项,viewGroup,false);
返回新的ViewHolder(视图);
}
//初始化viewholder类。
公共类ViewHolder扩展了RecyclerView.ViewHolder{
倒计时;
私人文本视图游戏倒计时;
公共视图持有者(视图){
超级(视图);
game\u倒计时=view.findviewbyd(R.id.game\u倒计时);
}
}
@凌驾
BindViewHolder上的公共无效(最终升级竞赛回收器适配器。ViewHolder ViewHolder,最终整型位置){
if(viewHolder.timer!=null)
{
viewHolder.timer.cancel();
}
//在游戏倒计时视图中启动倒计时计时器。
viewHolder.timer=新的倒计时(live_和即将到来的_竞赛.get(position).getStart_time(),500){
公共void onTick(长毫秒未完成){
长秒sinmilli=1000;
长分钟单位为毫秒=秒单位为毫秒*60;
长小时毫米=分钟毫米*60;
长时间延迟小时=完成前的毫秒/小时百万分之一;
millisUntilFinished=millisUntilFinished%hoursInMilli;
长延时分钟=完成前的毫秒数/分钟数毫秒数;
millisUntilFinished=millisUntilFinished%minutesInMilli;
长延时秒=毫秒到完成/秒毫秒;
字符串yy=String.format(“%02d:%02d:%02d”,elapsedHours,elapsedMinutes,elapsedSeconds);
viewHolder.game_倒计时.setText(yy);
}
公共无效onFinish(){
viewHolder.game_倒计时.setText(“00:00:00”);
现场和即将到来的比赛。移除(位置);
notifyDataSetChanged();
}
}.start();
}
这可能不是正确的方法,因为我想我不应该每次都在BindViewHolder上启动一个新的计时器。我在堆栈溢出中找到了在启动新的计时器之前取消BindViewHolder上的viewholder计时器的代码,但这不起作用。我尝试了使用处理程序的另一个解决方案,它作为计时器运行良好,但即使在这种情况下一次,当删除该项时,它崩溃了。再次澄清一下,将有多个计时器同时结束,因此多个列表项将同时被删除,代码应该能够处理这一点


非常感谢您的帮助。谢谢。

如果我没有弄错,则删除项需要如下所示:
mDataset.remove(位置);notifyItemRemoved(位置);notifyItemRangeChanged(位置,mDataset.size())
@Jacky感谢您的回复。问题在于删除行。我已经在使用您提到的代码。它会引发索引越界异常,因为可能我正在尝试同时删除两个项目。同样,如果我一次删除一个项目,此代码可以正常工作。是的,确实是由于您的删除项目。但会更正否t如果已更改,适配器可以自行更新,而无需进行太多更改trouble@Jacky通知部分可以,但我需要删除该项。如果我不删除该项,则调用已更改的数据集是没有意义的,删除部分会给我带来麻烦。当计时器到达时,假设您有2项,一旦删除了第一项,如果通知正确,则n第二项的位置将相应更新。
索引越界
发生在第二项的代码到达
删除
时。将尝试创建一个简单的应用程序,并就此发布答案