Android开发:倒计时结束后如何将RecyclerView对应item移动到列表底部

实现方案
你需要在现有Adapter类中完成逻辑调整,核心修改点有3个:
- 修正原代码的结构错误:原代码中倒计时逻辑写在了
onBindViewHolder方法外部,会直接编译报错,需要把这部分逻辑移到onBindViewHolder内部 - 给Holder类增加CountDownTimer成员变量,避免列表滚动复用Item时出现倒计时错乱
- 在倒计时的
onFinish回调中执行item位置调整逻辑:取出当前完成倒计时的item数据,从列表原位置删除后追加到列表末尾,再调用RecyclerView的对应通知方法触发移动动画
修改后的完整代码如下:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Holder> { // 原有变量保留 private ArrayList<UserDet> UserArrayList; private HomeFragment context; String timey ; // 构造方法不变 public MyAdapter(ArrayList<UserDet> UserArrayList, HomeFragment context) { this.UserArrayList = UserArrayList; this.context = context; } @NonNull @Override public MyAdapter.Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new Holder(LayoutInflater.from(context.getActivity()).inflate(R.layout.onerowforrecview, parent, false)); } @Override public void onBindViewHolder(@NonNull Holder holder, int position) { // 先取消Holder上绑定的上一个倒计时,避免列表复用错乱 if (holder.countDownTimer != null) { holder.countDownTimer.cancel(); } UserDet userDet = UserArrayList.get(position); holder.ques_name_h.setText(userDet.getCategoryName()); long timer = userDet.getCategoryTime().toDate().getTime(); final long currentTime = System.currentTimeMillis(); long expiryTime = timer - currentTime; // 把倒计时实例绑定到Holder上 holder.countDownTimer = new CountDownTimer(expiryTime, 1000) { public void onTick(long millisUntilFinished) { long seconds = millisUntilFinished / 1000; long minutes = seconds / 60; long hours = minutes / 60; long days = hours / 24; timey = days+"d, " +hours % 24 + "h left"; holder.ques_time_h.setText(timey); } public void onFinish() { holder.ques_amount_h.setButtonColor(R.color.teal_200); holder.itemView.setEnabled(false); holder.ques_time_h.setText("Time up!"); // 核心位置调整逻辑 int currentPos = holder.getAdapterPosition(); // 校验位置有效性,避免异步回调时item已经被移除导致崩溃 if (currentPos != RecyclerView.NO_POSITION && currentPos < UserArrayList.size()) { // 取出当前item的数据 UserDet finishedItem = UserArrayList.get(currentPos); // 从原位置删除 UserArrayList.remove(currentPos); // 追加到列表末尾 UserArrayList.add(finishedItem); // 通知RecyclerView执行item移动动画 notifyItemMoved(currentPos, UserArrayList.size() - 1); } } }.start(); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent= new Intent(context.getActivity(), TournamentDetails.class); context.startActivity(intent); } }); } @Override public int getItemCount() { return UserArrayList.size(); } // Holder类新增CountDownTimer成员变量 public class Holder extends RecyclerView.ViewHolder { // 补充你自己的控件声明,以下为示例,替换为实际控件类型和id TextView ques_name_h, ques_time_h; Button ques_amount_h; CountDownTimer countDownTimer; public Holder(@NonNull View itemView) { super(itemView); // 补充控件findViewById逻辑 ques_name_h = itemView.findViewById(R.id.xxx); ques_time_h = itemView.findViewById(R.id.xxx); ques_amount_h = itemView.findViewById(R.id.xxx); } } }
补充说明
如果后续需要item倒计时结束后直接移出列表而非移到底部,只需要删除UserArrayList.add(finishedItem)这行代码,同时把notifyItemMoved替换为notifyItemRemoved(currentPos)即可。
内容的提问来源于stack exchange,提问作者Kumar Harsh
相关产品推荐
相关产品推荐

