RecyclerView实现包含倒计时的列表
功能:
1.包含计时器的 RecyclerView 列表
2.支持刷新和加载更多(分页加载)
效果图:
实现思路:
内部维护一个 map, key 为 adapter 绑定数据模型的唯一 id, value 为绑定的数据模型,
map 保存需要更新倒计时的 model,
启动一个定时器, 每个间隔周期遍历一次 map, 取出 map 中数据, 更新 model 的倒计时属性, 最后局部更新 item.
主要代码 adapter :
-
package com.example.recyclertimerdemo
-
-
import android.util.ArrayMap
-
import android.view.LayoutInflater
-
import android.view.View
-
import android.view.ViewGroup
-
import android.widget.Button
-
import android.widget.TextView
-
import androidx.recyclerview.widget.RecyclerView
-
import io.reactivex.Observable
-
import io.reactivex.android.schedulers.AndroidSchedulers
-
import io.reactivex.disposables.Disposable
-
import io.reactivex.schedulers.Schedulers
-
import java.util.*
-
import java.util.concurrent.TimeUnit
-
-
-
private const val COUNT_DOWN_TIME = 30
-
-
/**
-
* @Author: qqyang
-
* @Date: 2022/6/8
-
* @Description:
-
* <p>
-
* 内部维护一个 map, key 为 adapter 绑定数据模型的唯一 id, value 为绑定的数据模型,
-
* map 保存需要更新倒计时的 model,
-
* 启动一个定时器, 每个间隔周期遍历一次 map, 取出 map 中数据, 更新 model 的倒计时属性, 最后局部更新 item.
-
* 注意: 不要忘记界面销毁时调用 [release] 释放资源.
-
* </p>
-
*/
-
class UserAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
-
-
/**
-
* rxjava 实现倒计时.
-
*/
-
private var mTimerSubscribe: Disposable? = null
-
-
private val mList: MutableList<User> by lazy { LinkedList() }
-
-
/**
-
* 用来存储当前正在进行倒计时的 user.
-
*/
-
private val mUserMap by lazy { ArrayMap<Int, User>() }
-
-
-
fun clearData() {
-
mList.clear()
-
notifyDataSetChanged()
-
}
-
-
fun addDataList(dataList: List<User>) {
-
mList.addAll(dataList)
-
notifyDataSetChanged()
-
}
-
-
fun release() {
-
mTimerSubscribe?.dispose()
-
mTimerSubscribe = null
-
}
-
-
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
-
return UserViewHolder(
-
LayoutInflater.from(parent.context).inflate(R.layout.adapter_user, parent, false)
-
)
-
}
-
-
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
-
val user = mList[position]
-
user.itemPosition = position // 设置 item position.
-
val vh = holder as UserViewHolder
-
vh.tvName.text = user.name
-
if (user.isRunning()) {
-
disableCountDown(vh.btnCountDown)
-
holder.btnCountDown.text = "倒计时: ${user.countDownTime}S"
-
startTimer(user)
-
} else {
-
enableCountDown(vh.btnCountDown)
-
}
-
vh.btnCountDown.setOnClickListener {
-
user.countDownTime = COUNT_DOWN_TIME
-
holder.btnCountDown.text = "倒计时: ${user.countDownTime}S"
-
startTimer(user)
-
}
-
}
-
-
/**
-
* 局部更新倒计时 view.
-
*/
-
override fun onBindViewHolder(
-
holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>
-
) {
-
if (payloads.isEmpty()) {
-
super.onBindViewHolder(holder, position, payloads)
-
} else {
-
val user = payloads[0]
-
if (user is User && holder is UserViewHolder) {
-
if (user.isRunning()) {
-
// 如果正在进行倒计时, 禁止重复点击.
-
disableCountDown(holder.btnCountDown)
-
holder.btnCountDown.text = "倒计时: ${user.countDownTime}S"
-
} else {
-
enableCountDown(holder.btnCountDown)
-
}
-
}
-
}
-
}
-
-
override fun getItemCount() = mList.size
-
-
private fun enableCountDown(btn: Button) {
-
btn.isClickable = true
-
btn.text = "开始倒计时"
-
}
-
-
private fun disableCountDown(btn: Button) {
-
btn.isClickable = false
-
}
-
-
/**
-
* view holder.
-
*/
-
internal class UserViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
-
val tvName: TextView by lazy { itemView.findViewById(R.id.tvName) }
-
val btnCountDown: Button by lazy { itemView.findViewById(R.id.btnCountDown) }
-
}
-
-
/**
-
* 启动计时器.
-
*/
-
private fun startTimer(user: User) {
-
mUserMap[user.id] = user
-
if (null == mTimerSubscribe) {
-
// 间隔 1s.
-
mTimerSubscribe = Observable.interval(1, TimeUnit.SECONDS)
-
.subscribeOn(Schedulers.io())
-
.observeOn(AndroidSchedulers.mainThread())
-
.subscribe {
-
val iterator = mUserMap.entries.iterator()
-
while (iterator.hasNext()) {
-
val bean = iterator.next().value
-
bean.countDownTime -= 1
-
if (bean.countDownTime <= 0) { // 倒计时结束, 从列表移除数据.
-
iterator.remove()
-
}
-
considerNotifyItemChanged(bean)
-
}
-
}
-
}
-
}
-
-
/**
-
* 考虑是否更新列表.
-
* 如果需要更新的数据已经不在列表中(ex: 进行了刷新操作, 刷新后, 接口返回的新数据列表中没有当前需要进行刷新倒计时的数据), 不进行更新.
-
*/
-
private fun considerNotifyItemChanged(user: User) {
-
mList.firstOrNull { it.id == user.id }?.let {
-
notifyItemChanged(user.itemPosition, user)
-
}
-
}
-
-
}
全部代码地址:
https://github.com/QQQQQQY/RecyclerViewTimerListDemo
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfiibkg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24