版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在Android中实现列表倒计时
怎么在Android中实现列表倒计时?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。CountDownTimer类用法
private
CountDownTimer
timer
=
new
CountDownTimer(30000,
1000)
{
//根据间隔时间来不断回调此方法,这里是每隔1000ms调用一次
@Override
public
void
onTick(long
millisUntilFinished)
{
//todo
millisUntilFinished为剩余时间,也就是30000
-
n*1000
}
//结束倒计时调用
@Override
public
void
onFinish()
{
//todo
}
};
//开始倒计时
timer.start();
//取消倒计时(译者:取消后,再次启动会重新开始倒计时)
timer.cancel();;代码实现先看核心,也就是CountDownAdapter类,这里就简化UI,每个item只有一个textView来显示倒计时,布局XML就不放了,直接放代码class
CountDownAdapter(private
var
activity:
ListActivity,
private
var
data:
ArrayList<Date>,
private
var
systemDate:
Date)
:
BaseAdapter()
{
private
val
timeMap
=
HashMap<TextView,
MyCountDownTimer>()
private
val
handler
=
Handler()
private
val
runnable
=
object
:
Runnable
{
override
fun
run()
{
if
(systemDate
!=
null)
{
systemDate.time
=
systemDate.time
+
1000
Log.i("xujf",
"服务器时间线程==="
+
systemDate
+
"==for=="
+
this)
handler.postDelayed(this,
1000)
}
}
}
init
{
handler.postDelayed(runnable,
1000)
}
override
fun
getView(position:
Int,
convertView:
View?,
parent:
ViewGroup?):
View
{
var
v:
View
var
tag:
ViewHolder
var
vo
=
data[position]
if
(null
==
convertView)
{
v
=
activity.layoutInflater.inflate(R.layout.item_count_down,
null)
tag
=
ViewHolder(v)
v.tag
=
tag
}
else
{
v
=
convertView
tag
=
v.tag
as
ViewHolder
}
//获取控件对应的倒计时控件是否存在,
存在就取消,
解决时间重叠问题
var
tc:
MyCountDownTimer?
=
timeMap[tag.tvTime]
if
(tc
!=
null)
{
tc.cancel()
tc
=
null
}
//计算时间差
val
time
=
getDistanceTimeLong(systemDate,
vo)
//创建倒计时,与控件绑定
val
cdu
=
MyCountDownTimer(position,
time,
1000,
tag.tvTime)
cdu.start()
//[醒目]此处需要map集合将控件和倒计时类关联起来
timeMap.put(tag.tvTime,
cdu)
return
v
}
/**
*
退出时清空所有item的计时器
*/
fun
cancelAllTimers()
{
var
s:
Set<MutableMap.MutableEntry<TextView,
MyCountDownTimer>>?
=
timeMap.entries
var
it:
Iterator<*>?
=
s!!.iterator()
while
(it!!.hasNext())
{
try
{
val
pairs
=
it.next()
as
MutableMap.MutableEntry<*,
*>
var
cdt:
MyCountDownTimer?
=
pairs.value
as
MyCountDownTimer
cdt!!.cancel()
cdt
=
null
}
catch
(e:
Exception)
{
}
}
it
=
null
s
=
null
timeMap.clear()
}
fun
removeTimer(){
handler?.removeCallbacks(runnable)
}
fun
reSetTimer(date:
Date)
{
removeTimer()
systemDate
=
date
handler.postDelayed(runnable,
1000)
}
override
fun
getItem(position:
Int):
Any
=
data[position]
override
fun
getItemId(position:
Int):
Long
=
0L
override
fun
getCount():
Int
=
data.size
internal
inner
class
ViewHolder(view:
View)
{
var
tvTime
=
view.findViewById<TextView>(R.id.tv_time)
}
/**
*
倒计时类,每间隔countDownInterval时间调用一次onTick()
*
index参数可去除,在这里只是为了打印log查看倒计时是否运行
*/
private
inner
class
MyCountDownTimer(internal
var
index:
Int,
millisInFuture:
Long,
internal
var
countDownInterval:
Long,
internal
var
tv:
TextView
)
:
CountDownTimer(millisInFuture,
countDownInterval)
{
override
fun
onTick(millisUntilFinished:
Long)
{
//millisUntilFinished为剩余时间长
Log.i("xujf",
"====倒计时还活着===第
$index
项item======")
//设置时间格式
val
m
=
millisUntilFinished
/
countDownInterval
val
hour
=
m
/
(60
*
60)
val
minute
=
(m
/
60)
%
60
val
s
=
m
%
60
tv.text
=
"倒计时
(${hour}小时${minute}分${s}秒)"
}
override
fun
onFinish()
{
tv.text
=
"倒计时结束"
//todo
可以做一些刷新动作
}
}
/**
*
时间工具,返回间隔时间长
*/
fun
getDistanceTimeLong(one:
Date,
two:
Date):
Long
{
var
diff
=
0L
try
{
val
time1
=
one.time
val
time2
=
two.time
if
(time1
<
time2)
{
diff
=
time2
-
time1
}
else
{
diff
=
time1
-
time2
}
}
catch
(e:
Exception)
{
e.printStackTrace()
}
return
diff
}
}这里主要的创建一个线程来保持服务器时间和N个item倒计时的“走”动。保持服务器时间没什么好说的,就是Handler配合Runnable的循环调用,注意的是,当activity销毁时,别忘了调用CountDownAdapter的removeTimer()方法来取消handler的回调,防止内存泄漏。重点就是item里的倒计时的线程控制,这里参照网上的一个比较好的方法,就是用HashMap<TextView,MyCountDownTimer>()来让MyCountDownTimer和item里的TextView关联起来,也就是每个item对应一个CountDownTimer,当关闭页面时或者刷新list时,可利用cancelAllTimers()方法来清除所有关联,避免内存泄漏。以下是ListActivity,伪造一些时间数据class
ListActivity
:
AppCompatActivity()
{
private
val
list:
ArrayList<Date>
=
ArrayList()
private
var
countDownAdapter:
CountDownAdapter?
=
null
override
fun
onCreate(savedInstanceState:
Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_list)
getDate()
setDate()
}
private
fun
setDate()
{
if
(countDownAdapter
==
null)
{
countDownAdapter
=
CountDownAdapter(this,
list,
Date())
lv_count_down.adapter
=
countDownAdapter
lv_count_down.onItemClickListener
=
AdapterView.OnItemClickListener
{
adapterView,
view,
i,
l
->
val
intent
=
Intent(ListActivity@this,
Main2Activity::class.java)
startActivity(intent)
}
}
else
{
//刷新数据时,重置本地服务器时间
countDownAdapter!!.reSetTimer(Date())
countDownAdapter!!.notifyDataSetChanged()
}
}
private
fun
getDate()
{
for
(i
in
1..20)
{
var
date
=
Date(Date().time
+
i
*
1000
*
60
*
30)
list.add(date)
}
}
override
fun
onDestroy()
{
countDownAdapter?.cancelAllTimers()
countDownAdapter?.removeTimer()
super.onDestroy()
}
}这
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2022年中国国家画院应届毕业生招聘考试试卷及答案解析
- 2022年省阜阳市第五人民医院校园招聘考试试卷及答案解析
- 2023年中国南水北调集团生态环保有限公司及下属公司招聘考试真题及答案
- 2023年秦皇岛市抚宁区赴高校次选聘人事代理教师工作考试真题及答案
- 2023年辽宁鞍山(国家)高新技术产业开发区社会招聘教师现场考试真题及答案
- 2023年阿坝州阿坝县人民法院招聘聘用制书记员考试真题及答案
- 邮政银行实习心得体会范文六篇
- 2024年河北省安全员A证试题题库
- 儿童早期的认知发展-儿童游戏(现代游戏理论)
- 高分子在紫杉醇药物中的应用
- 小学数学课堂“教学评一致性”的有效实践
- 部编小学语文单元作业设计六年级下册第一单元
- 高考备考经验交流课件
- 2023年江苏省南京江北新区大数据管理中心招聘5人笔试参考题库(共500题)答案详解版
- 2023安徽职业技术学院人才招聘67人笔试参考题库(共500题)答案详解版
- 江苏省高中数学优秀课评比课件——直线与平面垂直.ppt
- 火灾处理流程图
- 金话筒主持人大赛ppt
- 自制音标卡(4A纸张打印版);
- 260系列电子胃肠镜清洗灭菌消毒手册
- 形式发票PROFORMAINVOICE
评论
0/150
提交评论