使用payload局部刷新机制简单实现RecyclerView列表倒计时

本方案采用RecyclerView的payload机制实现
RecyclerView局部刷新机制——payload

实现点击条目实现某一个条目的倒计时 和 所有条目一起倒计时
在这里插入图片描述

下面给出具体代码实现:

//列表中的倒计时刷新测试
class RefreshTimeActivity : BaseActivity() {

    private val binding by lazy { ActivityRefreshTimeBinding.inflate(layoutInflater) }
    private val viewModel: viewModel by inject()

    private lateinit var refreshTimeAdapter: RefreshTimeAdapter


    private val mList = mutableListOf<Apis.WanBanner>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        initView()
        initObserver()
        initData()
    }

    override fun initView() {
        super.initView()
        binding.swipeList.setOnRefreshListener {
            viewModel.getBanners()
        }
        refreshTimeAdapter = RefreshTimeAdapter(this, mList)
        binding.rvList.layoutManager = LinearLayoutManager(this)
        binding.rvList.adapter = refreshTimeAdapter
    }

    override fun initObserver() {
        super.initObserver()
        viewModel.getBanners.observe(this, Observer {
            if (it.isSucceed()) {
                it.data()?.let { list ->
                    mList.clear()
                    mList.addAll(list)
                    addTestTime()
                    refreshTimeAdapter.notifyDataSetChanged()
                    binding.swipeList.isRefreshing = false
                }
            }
        })
    }

    private fun addTestTime(){
        for (item in mList.withIndex()){
            //3600秒 = 1小时
            val time = System.currentTimeMillis()+(item.index+1).times(3600000).toLong()
            item.value.startTime = time
        }
    }

    override fun initData() {
        super.initData()
        viewModel.getBanners()
    }


    class RefreshTimeAdapter(private val context: Context, private val list: List<Apis.WanBanner>) :
        RecyclerView.Adapter<RecyclerView.ViewHolder>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            val binding = ItemWanBinding.inflate(LayoutInflater.from(parent.context))
            return ViewHolder(binding)
        }

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            if (holder is RefreshTimeAdapter.ViewHolder) {
                val item = list[position]
                holder.binding.tvTitle.text = item.title
                holder.binding.tvStartTime.text = "开售时间:${TimeUtils.getTime(item.startTime)}"
                Glide.with(context).load(item.imagePath).apply(
                    RequestOptions.bitmapTransform(
                        RoundedCorners(20)
                    )
                )
                    .into(holder.binding.ivWan)

                //1.点击Item倒计时
                //holder.binding.tvTime.setOnClickListener {
                //    notifyItemChanged(holder.layoutPosition, "123");
                //}

                //2.所有Item直接倒计时
                CoroutineScope(Dispatchers.Main).launch{
                    notifyItemChanged(holder.layoutPosition, "payload");
                }
            }
        }

        override fun onBindViewHolder(
            holder: RecyclerView.ViewHolder,
            position: Int,
            payloads: MutableList<Any>
        ) {
            super.onBindViewHolder(holder, position, payloads)
            if (payloads.isEmpty()) {
                onBindViewHolder(holder, position)
            } else {
                if (holder is RefreshTimeAdapter.ViewHolder) {
                    val item = list[position]
                    CoroutineScope(Dispatchers.Main).launch {
                        holder.binding.tvTime.text = "开售倒计时:${item.startTime.calculateTime()}"
                        delay(1000)
                        notifyItemChanged(holder.layoutPosition, "payload")
                    }
                }

            }
        }

        override fun getItemCount(): Int {
            return list.size
        }

        inner class ViewHolder(val binding: ItemWanBinding) : RecyclerView.ViewHolder(binding.root)

    }

}


val twoFormat = DecimalFormat("00")
fun Long.calculateTime(): String {
    //val currentTime = SystemClock.elapsedRealtime()
    val currentTime = System.currentTimeMillis()
    val remains = this - currentTime
    if (remains <= 0) {
        return ""
    }
    val day = remains / (24 * 60 * 60 * 1000)
    val hour = remains / (60 * 60 * 1000) % 24
    val minutes = remains / (60 * 1000) % 60
    val second = remains / 1000 % 60
    return if (day > 0) {
        "${day}天${hour}小时${minutes}分"
    } else {
        "${twoFormat.format(hour)}:${twoFormat.format(minutes)}:${twoFormat.format(second)}"
    }
}

addTestTime方法:每个item的时间间隔1小时,
使用notifyItemChanged 只更新单个条目的单个view,
CoroutineScope 开启协程延迟一秒后再次更新

布局:activity_refresh_time

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipe_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>


</LinearLayout>

至此,简单的列表倒计时就实现了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦A梦z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值