[英]How to use multiple timer 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?我该如何解决?
Because your code is written that way.因为你的代码是这样写的。
onBindViewHolder(..)
is called whenever you scroll up/down and the view goes outside of visible area.每当您向上/向下滚动并且视图超出可见区域时,就会调用
onBindViewHolder(..)
。 Then that view is recycled and bound again to new list item (from model list).然后该视图被回收并再次绑定到新列表项(来自模型列表)。 That's how it got the name
RecyclerView
.这就是它获得名称
RecyclerView
。
To solve your problem, you need to put your countdown timer initialization codes inside model list item initialization (eg Today
constructor).要解决您的问题,您需要将倒数计时器初始化代码放在模型列表项初始化(例如
Today
构造函数)中。
Then the countdown timer will start and remain running within the Today object and inside onBindViewHolder(..)
just grab the remaining time value from that Today
object.然后倒数计时器将启动并在 Today 对象内保持运行,而在
onBindViewHolder(..)
只需从该Today
对象中获取剩余时间值。
Hope this helps!!希望这可以帮助!!
Update I am not experienced in kotlin.
更新我对 kotlin 没有经验。 So you may need to modify it according to kotlin.
所以你可能需要根据 kotlin 修改它。 At some point you have
MutableList<Today>
preparation code right?在某些时候你有
MutableList<Today>
准备代码对吗?while creating a Today object, pass the adapter object as a constructor parameter.
在创建 Today 对象时,将适配器对象作为构造函数参数传递。
The following block should be inside your
Today
class.下面的块应该在你的
Today
类中。var newCountDownTimer : CountDownTimer var currentVal : String init { 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 currentVal = String.format("%02d", hours) + ":" + String.format( "%02d", minutes ) + ":" + String.format("%02d", seconds) // call adapter.notifyItemChanged(..) here } override fun onFinish() { //here you should call the adapter.notifyItemChanged(..) function with the position of this model in the model list } }.start() }
your
onBindViewHolder
should look like this:您的
onBindViewHolder
应如下所示:override fun onBindViewHolder(holder: MyHolder, position: Int) { val modelUse = model[position] holder.setData(modelUse) }
inside
Holder.setData(..)
function add this code在
Holder.setData(..)
函数中添加此代码rowMain_timer.text = model.currentVal
Let me know if it helps.
如果有帮助,请告诉我。
have you tried making use of 1. onSaveInstanceState(Bundle state)
2.Restore state in the onRestoreInstanceState()
3. and onResume()
.您是否尝试过在
onRestoreInstanceState()
3. 和onResume()
使用 1. onSaveInstanceState(Bundle state)
2.Restore 状态。
this way you can keep track on your RecyclerList data.这样您就可以跟踪您的 RecyclerList 数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.