android 列表倒计时,Android利用RecyclerView实现列表倒计时效果
最近面試時,面試官問了一個列表倒計時效果如何實現(xiàn),現(xiàn)在記錄一下。
運行效果圖
實現(xiàn)思路
實現(xiàn)方法主要有兩個:
1.為每個開始倒計時的item啟動一個定時器,再做更新item處理;
2.只啟動一個定時器,然后遍歷數(shù)據(jù),再做再做更新item處理。
經(jīng)過思考,包括性能、實現(xiàn)等方面,決定使用第2種方式實現(xiàn)。
實現(xiàn)過程
數(shù)據(jù)實體
/**
* 總共的倒計時的時間(結(jié)束時間-開始時間),單位:毫秒
* 例: 2019-02-23 11:00:30 與 2019-02-23 11:00:00 之間的相差的毫秒數(shù)
*/
private long totalTime;
/**
* 倒計時是否在暫停狀態(tài)
*/
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()) {//不處于暫停狀態(tài)
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;
}
}
};
性能優(yōu)化方面
1.調(diào)用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;//數(shù)據(jù)
private Handler mHandler;//線程調(diào)度,用來更新列表
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);
}
/**
* 設(shè)置新的數(shù)據(jù)源
*
* @param list 數(shù)據(jù)
*/
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()) {//不處于暫停狀態(tài)
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);
}
}
}
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持。
總結(jié)
以上是生活随笔為你收集整理的android 列表倒计时,Android利用RecyclerView实现列表倒计时效果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 新浪微博的点赞功能实现,
- 下一篇: 阿里云管理Android项目,Andro