android item倒计时功能,Android利用RecyclerView实现列表倒计时效果
发布日期:2021-06-24 16:21:07 浏览次数:2 分类:技术文章

本文共 5859 字,大约阅读时间需要 19 分钟。

最近面试时,面试官问了一个列表倒计时效果如何实现,现在记录一下。

运行效果图

5cd95ff9d5c3b4a34cdbec93b00872de.gif

实现思路

实现方法主要有两个:

1.为每个开始倒计时的item启动一个定时器,再做更新item处理;

2.只启动一个定时器,然后遍历数据,再做再做更新item处理。

经过思考,包括性能、实现等方面,决定使用第2种方式实现。

实现过程

数据实体

/**

* 总共的倒计时的时间(结束时间-开始时间),单位:毫秒

* 例: 2019-02-23 11:00:30 与 2019-02-23 11:00:00 之间的相差的毫秒数

*/

private long totalTime;

/**

* 倒计时是否在暂停状态

*/

private boolean isPause = true;

倒计时

Timer

mTimer.schedule(mTask, 0, 1000);

TimerTask

class MyTask extends TimerTask {

@Override

public void run() {

if (mList.isEmpty()) {

return;

}

int size = mList.size();

CountDownTimerBean bean;

long totalTime;

for (int i = 0; i < size; i++) {

bean = mList.get(i);

if (!bean.isPause()) {//不处于暂停状态

totalTime = bean.getTotalTime() - 1000;

if (totalTime <= 0) {

bean.setPause(true);

bean.setTotalTime(0);

}

bean.setTotalTime(totalTime);

Message message = mHandler.obtainMessage(1);

message.arg1 = i;

mHandler.sendMessage(message);

}

}

}

}

线程交互更新item

mHandler = new Handler(Looper.getMainLooper()) {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:

notifyItemChanged(msg.arg1, "update-time");

break;

}

}

};

性能优化方面

1.调用notifyItemChanged()方法后,不要更新整个item(比如说item包含图片,不需要变的),所以要重写onBindViewHolder( Holder , int , List )方法:

@Override

public void onBindViewHolder(@NonNull Holder holder, int position, @NonNull List payloads) {

if (payloads.isEmpty()) {

onBindViewHolder(holder, position);

return;

}

//更新某个控件,比如说只需要更新时间信息,其他不用动

CountDownTimerBean bean = mList.get(position);

long day = bean.getTotalTime() / (1000 * 60 * 60 * 24);

long hour = (bean.getTotalTime() / (1000 * 60 * 60) - day * 24);

long min = ((bean.getTotalTime() / (60 * 1000)) - day * 24 * 60 - hour * 60);

long s = (bean.getTotalTime() / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);

holder.tvTime.setText("剩余时间: " + day + "天" + hour + "小时" + min + "分" + s + "秒");

holder.btnAction.setText(bean.isPause() ? "开始" : "暂停");

holder.btnAction.setEnabled(bean.getTotalTime() != 0);

}

2.销毁资源操作:

/**

* 销毁资源

*/

public void destroy() {

mHandler.removeMessages(1);

if (mTimer != null) {

mTimer.cancel();

mTimer.purge();

mTimer = null;

}

}

RecyclerView.Adapter部分源码

public class CountDownTimerAdapter extends RecyclerView.Adapter {

private static final String TAG = "CountDownTimerAdapter->";

private List mList;//数据

private Handler mHandler;//线程调度,用来更新列表

private Timer mTimer;

private MyTask mTask;

public CountDownTimerAdapter() {

mList = new ArrayList<>();

mHandler = new Handler(Looper.getMainLooper()) {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:

notifyItemChanged(msg.arg1, "update-time");

break;

}

}

};

mTask = new MyTask();

}

public void bindAdapterToRecyclerView(@NonNull RecyclerView view) {

view.setAdapter(this);

}

/**

* 设置新的数据源

*

* @param list 数据

*/

public void setNewData(@NonNull List list) {

destroy();

mList.clear();

mList.addAll(list);

notifyDataSetChanged();

if (mTimer == null) {

mTimer = new Timer();

}

mTimer.schedule(mTask, 0, 1000);

}

/**

* 销毁资源

*/

public void destroy() {

mHandler.removeMessages(1);

if (mTimer != null) {

mTimer.cancel();

mTimer.purge();

mTimer = null;

}

}

@NonNull

@Override

public Holder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_count_down_timer, viewGroup, false);

return new Holder(view);

}

@Override

public void onBindViewHolder(@NonNull Holder holder, int position, @NonNull List payloads) {

if (payloads.isEmpty()) {

onBindViewHolder(holder, position);

return;

}

//更新某个控件,比如说只需要更新时间信息,其他不用动

CountDownTimerBean bean = mList.get(position);

long day = bean.getTotalTime() / (1000 * 60 * 60 * 24);

long hour = (bean.getTotalTime() / (1000 * 60 * 60) - day * 24);

long min = ((bean.getTotalTime() / (60 * 1000)) - day * 24 * 60 - hour * 60);

long s = (bean.getTotalTime() / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);

holder.tvTime.setText("剩余时间: " + day + "天" + hour + "小时" + min + "分" + s + "秒");

holder.btnAction.setText(bean.isPause() ? "开始" : "暂停");

holder.btnAction.setEnabled(bean.getTotalTime() != 0);

}

@Override

public void onBindViewHolder(@NonNull final Holder holder, int position) {

holder.ivIcon.setImageResource(R.mipmap.ic_launcher_round);

final CountDownTimerBean bean = mList.get(position);

long day = bean.getTotalTime() / (1000 * 60 * 60 * 24);

long hour = (bean.getTotalTime() / (1000 * 60 * 60) - day * 24);

long min = ((bean.getTotalTime() / (60 * 1000)) - day * 24 * 60 - hour * 60);

long s = (bean.getTotalTime() / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);

holder.tvTime.setText("剩余时间: " + day + "天" + hour + "小时" + min + "分" + s + "秒");

holder.btnAction.setText(bean.isPause() ? "开始" : "暂停");

holder.btnAction.setEnabled(bean.getTotalTime() != 0);

holder.btnAction.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if (bean.isPause()) {

bean.setPause(false);

holder.btnAction.setText("暂停");

} else {

bean.setPause(true);

holder.btnAction.setText("开始");

}

}

});

}

@Override

public int getItemCount() {

return mList.size();

}

class Holder extends RecyclerView.ViewHolder {

private ImageView ivIcon;

private TextView tvTime;

private Button btnAction;

Holder(@NonNull View itemView) {

super(itemView);

ivIcon = itemView.findViewById(R.id.iv_icon);

tvTime = itemView.findViewById(R.id.tv_time);

btnAction = itemView.findViewById(R.id.btn_action);

}

}

class MyTask extends TimerTask {

@Override

public void run() {

if (mList.isEmpty()) {

return;

}

int size = mList.size();

CountDownTimerBean bean;

long totalTime;

for (int i = 0; i < size; i++) {

bean = mList.get(i);

if (!bean.isPause()) {//不处于暂停状态

totalTime = bean.getTotalTime() - 1000;

if (totalTime <= 0) {

bean.setPause(true);

bean.setTotalTime(0);

}

bean.setTotalTime(totalTime);

Message message = mHandler.obtainMessage(1);

message.arg1 = i;

mHandler.sendMessage(message);

}

}

}

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

转载地址:https://blog.csdn.net/weixin_33780516/article/details/117321231 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:鸿蒙非手机系统,新系统正式定档,华为高管明确表态,鸿蒙不是安卓的替代品!...
下一篇:excel函数怎么用android,GitHub - huangting924/Android_Excel: 在android中生成excel

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月24日 10时37分30秒