[英]How to use multiple countDownTimer into recyclerView on Android
In my application i want use multiple CountDownerTimer
for show offer times into RecyclerView
. 在我的应用程序中,我想使用多个
CountDownerTimer
将显示提供时间放入RecyclerView
。
For write this application i used Kotlin language. 为了编写这个应用程序,我使用了Kotlin语言。
I write below codes, but when scrolling on recyclerView
's items start again this timer ! 我写下面的代码,但滚动到
recyclerView
的项目再次启动这个计时器 !
My mean is, timer started from 4:19 sec, when scrolling on items and after 10sec show me 4:19 again instead of 4:09 ! 我的意思是,计时器从4:19秒开始,当滚动项目时, 10秒后再次显示4:19而不是4:09 !
Activity codes: 活动代码:
class MainActivity : AppCompatActivity() {
private lateinit var apisList: ApisList
private lateinit var retrofit: Retrofit
private lateinit var todayAdapter: AuctionsTodayAdapter
private val todayModel: MutableList<Today> = mutableListOf()
private lateinit var layoutManager: RecyclerView.LayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Initialize
retrofit = ApiClient.instance
apisList = retrofit.create(ApisList::class.java)
todayAdapter = AuctionsTodayAdapter(themedContext, todayModel)
layoutManager = LinearLayoutManager(themedContext)
//RecyclerView
main_list.setHasFixedSize(true)
main_list.layoutManager = layoutManager
main_list.adapter = todayAdapter
if (isNetworkAvailable()) getData(1, 10)
}
private fun getData(page: Int, limit: Int) {
main_loader.visibility = View.VISIBLE
val call = apisList.getAuctionsToday(page, limit)
call.let {
it.enqueue(object : Callback<AuctionsTodayResponse> {
override fun onFailure(call: Call<AuctionsTodayResponse>, t: Throwable) {
main_loader.visibility = View.GONE
Log.e("auctionsTodayList", t.message)
}
override fun onResponse(call: Call<AuctionsTodayResponse>, response: Response<AuctionsTodayResponse>) {
if (response.isSuccessful) {
response.body()?.let { itBody ->
main_loader.visibility = View.GONE
if (itBody.toString().isNotEmpty()) {
todayModel.clear()
todayModel.addAll(itBody.res.today)
todayAdapter.notifyDataSetChanged()
}
}
}
}
})
}
}
}
Adapter codes: 适配器代码:
class AuctionsTodayAdapter(val context: Context, val model: MutableList<Today>) :
RecyclerView.Adapter<AuctionsTodayAdapter.MyHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
val view = LayoutInflater.from(context).inflate(R.layout.row_main_list, parent, false)
val holder = MyHolder(view)
//holder.setIsRecyclable(false)
return holder
}
override fun getItemCount(): Int {
return model.size
}
override fun onBindViewHolder(holder: MyHolder, position: Int) {
val modelUse = model[position]
holder.setData(modelUse)
if (holder.newCountDownTimer != null) {
holder.newCountDownTimer!!.cancel()
}
var timer = modelUse.calculateEnd
timer = timer * 1000
holder.newCountDownTimer = object : CountDownTimer(timer, 1000) {
override fun onTick(millisUntilFinished: Long) {
var seconds = (millisUntilFinished / 1000).toInt()
val hours = seconds / (60 * 60)
val tempMint = seconds - hours * 60 * 60
val minutes = tempMint / 60
seconds = tempMint - minutes * 60
holder.rowMain_timer.rowMain_timer.text =
String.format("%02d", hours) + ":" + String.format(
"%02d",
minutes
) + ":" + String.format("%02d", seconds)
}
override fun onFinish() {
holder.rowMain_timer.text = "00:00:00"
}
}.start()
}
inner class MyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var newCountDownTimer: CountDownTimer? = null
lateinit var rowMain_timer: TextView
init {
rowMain_timer = itemView.findViewById(R.id.rowMain_timer)
}
fun setData(model: Today) {
model.image.let {
Glide.with(context)
.load(Constants.MAIN_BASE_URL + it)
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.RESOURCE))
.into(itemView.rowMain_img)
}
model.title.let { itemView.rowMain_title.text = it }
}
}
How can I fix it? 我该如何解决?
How can I fix it? 我该如何解决?
ViewHolder is destroyed after you scroll it down or up (making not visible). 向下或向上滚动(不可见)后,ViewHolder将被销毁。 You should store timer value when it is destroyed and restore value when it is visible again.
您应该在销毁时存储计时器值,并在再次可见时恢复值。
Welcome to the recyclerview architecture! 欢迎来到recyclerview架构!
First of all you ought to understand that onBindViewHolder
can be called multiple times when a view is scrolled out and in from your screen, and you are starting a timer in every call. 首先,你应该明白,当一个视图从你的屏幕滚出来时,可以多次调用
onBindViewHolder
,并且你在每个调用中都会启动一个计时器。
What you should do is to save the timer remaining millis in onTick
in the viewHolder data and start a timer with this remaining time. 您应该做的是在viewHolder数据中将计时器剩余
onTick
保存在onTick
中,并使用剩余时间启动计时器。
In your viewHolder class, use a long variable that represents how much time left for coutDown, lets call it timeLeft
. 在你的viewHolder类中,使用一个long变量来表示coutDown剩余的时间,让我们称之为
timeLeft
。 In onTick
method type holder.timeLeft = millisUntilFinished
and in onFinish
method type holder.timeLeft = -1
. 在
onTick
方法类型holder.timeLeft = millisUntilFinished
和onFinish
方法类型holder.timeLeft = -1
。
Now, when initiating a new timer, after checking the timer is not null check, 现在,当启动一个新的计时器,检查计时器后不是空检查,
if (holder.leftTime > 0) {
holder.newCountDownTimer = object : CountDownTimer(holder.timeLeft, 1000) {
...
}
}
If the timeLeft is -1, decide what to do with the timer. 如果timeLeft为-1,则决定如何处理计时器。
Also, you might need to change the ticking from every 1000 millis to smaller number, like 100 millis, for better accurate timing when saving holder.timeLeft
. 此外,您可能需要将滴答从每1000毫秒更改为较小的数字,例如100毫秒,以便在保存
holder.timeLeft
时更准确的计时。
Hope this will answer your question. 希望这会回答你的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.