当我看到这个需求的时候第一时间想的是在adapter中去开启线程去控制item
上述方法带来的结果
- 实践之后发现只有最后一个item的计时器在运行;
- 我该在什么时候关闭线程,这也是个问题。
于是,简单嘛!多开几个线程就搞定了啊【手动滑稽】
-
应该开个线程池来管理,线程池的管理工具类还没有开始写,就发现问题了,我的item数量是几十上百的,到底要开多少线程?10个?20个?甚至是100个,管理起来及其复杂。我当时的心情是这样的:
- 上网搜索了一波儿,发现有人跟我差不多的需求,而且已经实现功能了,大体是说在activity中开启线程管理所有的item参考了一波儿;简直恍然大悟,犹如醍醐灌顶啊,于是继续开始了我的操作。参考博客传送门
开始我的操作
1、开启一个一秒更新一次的线程
private Handler mHandler;
private TimeThread timeThread;
private boolean isCloseThread = false;//是否关闭线程,默认为false
/**
* 定义一个跑时间的线程
*/
class TimeThread extends Thread {
@Override
public void run() {
do {
try {
Thread.sleep(1000);
Message msg = new Message();
msg.what = 1; //消息(一个整型值)
mHandler.sendMessage(msg);// 每隔1秒发送一个msg给mHandler
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (!isCloseThread);
}
}
2、实例化TimeThrea和Handler,并更新数据让时间跑起来
/**
* 显示计时时间
*/
private void setTimer() {
isCloseThread = false;
timeThread = new TimeThread();
if (!timeThread.isAlive()) {
timeThread.start();
}
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
for (int i = 0; i < usedParkSpaceAdapter.getData().size(); i++) {
if (usedParkSpaceAdapter.getData().get(i).getOrder() != null && isCloseThread == false) {
long startTime = usedParkSpaceAdapter.getData().get(i).getOrder().getParkStartTime();
String time = DateUtils.getCastToTime(startTime, (DateUtils.dateToLong(new Date()) / 1000));
try {
BaseViewHolder holder = (BaseViewHolder) recyclerView.findViewHolderForAdapterPosition(i);
holder.setText(R.id.park_used_time, time);
} catch (RuntimeException error) {
Log.e(TAG, "handleMessage:"+error.getMessage());
}
}
}
}
}
};
}
**解释**:
1.usedParkSpaceAdapter.getData().get(i);//拿到adapter中的数据;
2.BaseViewHolder holder = (BaseViewHolder) recyclerView.findViewHolderForAdapterPosition(i);//获取当前item的位置;
3.String time = DateUtils.getCastToTime(startTime, (DateUtils.dateToLong(new Date()) / 1000));//计算当前时间和开始时间的差并转化成 01:56:26 形式
4.holder.setText(R.id.park_used_time, time);//将时间显示出来(这里adapter用的是[BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper))
这种方式只刷新了显示时间相关的控件,并不需要去做很复杂的操作来刷新数据,甚至都不需要 notifyDataSetChanged();
3、adapter中的相关处理就很简单了,和平常没有差别,由于我的其他业务很多就不贴代码了。
4、最后关闭线程
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
isCloseThread = true;//看这一句就行
}
网友评论