• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

RecyclerView实现包含倒计时的列表

武飞扬头像
QQ丶
帮助1

功能:

1.包含计时器的 RecyclerView 列表

2.支持刷新和加载更多(分页加载)

效果图:

学新通

实现思路:

内部维护一个 map, key 为 adapter 绑定数据模型的唯一 id, value 为绑定的数据模型,

map 保存需要更新倒计时的 model,

启动一个定时器, 每个间隔周期遍历一次 map, 取出 map 中数据, 更新 model 的倒计时属性, 最后局部更新 item.

主要代码 adapter :

  1.  
    package com.example.recyclertimerdemo
  2.  
     
  3.  
    import android.util.ArrayMap
  4.  
    import android.view.LayoutInflater
  5.  
    import android.view.View
  6.  
    import android.view.ViewGroup
  7.  
    import android.widget.Button
  8.  
    import android.widget.TextView
  9.  
    import androidx.recyclerview.widget.RecyclerView
  10.  
    import io.reactivex.Observable
  11.  
    import io.reactivex.android.schedulers.AndroidSchedulers
  12.  
    import io.reactivex.disposables.Disposable
  13.  
    import io.reactivex.schedulers.Schedulers
  14.  
    import java.util.*
  15.  
    import java.util.concurrent.TimeUnit
  16.  
     
  17.  
     
  18.  
    private const val COUNT_DOWN_TIME = 30
  19.  
     
  20.  
    /**
  21.  
    * @Author: qqyang
  22.  
    * @Date: 2022/6/8
  23.  
    * @Description:
  24.  
    * <p>
  25.  
    * 内部维护一个 map, key 为 adapter 绑定数据模型的唯一 id, value 为绑定的数据模型,
  26.  
    * map 保存需要更新倒计时的 model,
  27.  
    * 启动一个定时器, 每个间隔周期遍历一次 map, 取出 map 中数据, 更新 model 的倒计时属性, 最后局部更新 item.
  28.  
    * 注意: 不要忘记界面销毁时调用 [release] 释放资源.
  29.  
    * </p>
  30.  
    */
  31.  
    class UserAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
  32.  
     
  33.  
    /**
  34.  
    * rxjava 实现倒计时.
  35.  
    */
  36.  
    private var mTimerSubscribe: Disposable? = null
  37.  
     
  38.  
    private val mList: MutableList<User> by lazy { LinkedList() }
  39.  
     
  40.  
    /**
  41.  
    * 用来存储当前正在进行倒计时的 user.
  42.  
    */
  43.  
    private val mUserMap by lazy { ArrayMap<Int, User>() }
  44.  
     
  45.  
     
  46.  
    fun clearData() {
  47.  
    mList.clear()
  48.  
    notifyDataSetChanged()
  49.  
    }
  50.  
     
  51.  
    fun addDataList(dataList: List<User>) {
  52.  
    mList.addAll(dataList)
  53.  
    notifyDataSetChanged()
  54.  
    }
  55.  
     
  56.  
    fun release() {
  57.  
    mTimerSubscribe?.dispose()
  58.  
    mTimerSubscribe = null
  59.  
    }
  60.  
     
  61.  
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
  62.  
    return UserViewHolder(
  63.  
    LayoutInflater.from(parent.context).inflate(R.layout.adapter_user, parent, false)
  64.  
    )
  65.  
    }
  66.  
     
  67.  
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
  68.  
    val user = mList[position]
  69.  
    user.itemPosition = position // 设置 item position.
  70.  
    val vh = holder as UserViewHolder
  71.  
    vh.tvName.text = user.name
  72.  
    if (user.isRunning()) {
  73.  
    disableCountDown(vh.btnCountDown)
  74.  
    holder.btnCountDown.text = "倒计时: ${user.countDownTime}S"
  75.  
    startTimer(user)
  76.  
    } else {
  77.  
    enableCountDown(vh.btnCountDown)
  78.  
    }
  79.  
    vh.btnCountDown.setOnClickListener {
  80.  
    user.countDownTime = COUNT_DOWN_TIME
  81.  
    holder.btnCountDown.text = "倒计时: ${user.countDownTime}S"
  82.  
    startTimer(user)
  83.  
    }
  84.  
    }
  85.  
     
  86.  
    /**
  87.  
    * 局部更新倒计时 view.
  88.  
    */
  89.  
    override fun onBindViewHolder(
  90.  
    holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>
  91.  
    ) {
  92.  
    if (payloads.isEmpty()) {
  93.  
    super.onBindViewHolder(holder, position, payloads)
  94.  
    } else {
  95.  
    val user = payloads[0]
  96.  
    if (user is User && holder is UserViewHolder) {
  97.  
    if (user.isRunning()) {
  98.  
    // 如果正在进行倒计时, 禁止重复点击.
  99.  
    disableCountDown(holder.btnCountDown)
  100.  
    holder.btnCountDown.text = "倒计时: ${user.countDownTime}S"
  101.  
    } else {
  102.  
    enableCountDown(holder.btnCountDown)
  103.  
    }
  104.  
    }
  105.  
    }
  106.  
    }
  107.  
     
  108.  
    override fun getItemCount() = mList.size
  109.  
     
  110.  
    private fun enableCountDown(btn: Button) {
  111.  
    btn.isClickable = true
  112.  
    btn.text = "开始倒计时"
  113.  
    }
  114.  
     
  115.  
    private fun disableCountDown(btn: Button) {
  116.  
    btn.isClickable = false
  117.  
    }
  118.  
     
  119.  
    /**
  120.  
    * view holder.
  121.  
    */
  122.  
    internal class UserViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
  123.  
    val tvName: TextView by lazy { itemView.findViewById(R.id.tvName) }
  124.  
    val btnCountDown: Button by lazy { itemView.findViewById(R.id.btnCountDown) }
  125.  
    }
  126.  
     
  127.  
    /**
  128.  
    * 启动计时器.
  129.  
    */
  130.  
    private fun startTimer(user: User) {
  131.  
    mUserMap[user.id] = user
  132.  
    if (null == mTimerSubscribe) {
  133.  
    // 间隔 1s.
  134.  
    mTimerSubscribe = Observable.interval(1, TimeUnit.SECONDS)
  135.  
    .subscribeOn(Schedulers.io())
  136.  
    .observeOn(AndroidSchedulers.mainThread())
  137.  
    .subscribe {
  138.  
    val iterator = mUserMap.entries.iterator()
  139.  
    while (iterator.hasNext()) {
  140.  
    val bean = iterator.next().value
  141.  
    bean.countDownTime -= 1
  142.  
    if (bean.countDownTime <= 0) { // 倒计时结束, 从列表移除数据.
  143.  
    iterator.remove()
  144.  
    }
  145.  
    considerNotifyItemChanged(bean)
  146.  
    }
  147.  
    }
  148.  
    }
  149.  
    }
  150.  
     
  151.  
    /**
  152.  
    * 考虑是否更新列表.
  153.  
    * 如果需要更新的数据已经不在列表中(ex: 进行了刷新操作, 刷新后, 接口返回的新数据列表中没有当前需要进行刷新倒计时的数据), 不进行更新.
  154.  
    */
  155.  
    private fun considerNotifyItemChanged(user: User) {
  156.  
    mList.firstOrNull { it.id == user.id }?.let {
  157.  
    notifyItemChanged(user.itemPosition, user)
  158.  
    }
  159.  
    }
  160.  
     
  161.  
    }
学新通

全部代码地址:

https://github.com/QQQQQQY/RecyclerViewTimerListDemo

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfiibkg
系列文章
更多 icon
同类精品
更多 icon
继续加载