【移动应用开发技术】怎么在Android中实现列表倒计时_第1页
【移动应用开发技术】怎么在Android中实现列表倒计时_第2页
【移动应用开发技术】怎么在Android中实现列表倒计时_第3页
【移动应用开发技术】怎么在Android中实现列表倒计时_第4页
【移动应用开发技术】怎么在Android中实现列表倒计时_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】怎么在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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论