背景

身为一名ui仔,不光要会画ui,也有可能接触一些其他的需求,就比方我做直播的时候,就需求做礼物的行列播放,用户送礼,然后客户收到音讯,然后一次播放礼物动画,这个需求很简略,自定义一个view而且里面有一个行列就可以搞定,可是假如要播放不同类型的内容,假如再去改这个ui,耦合度就会越来越大,那么这个view的定义就变了,那就太不酷啦,所以要将行列和ui拆开,所以咱们要完成一个行列功用,然后可以承受不同类型的参数,然后顺次履行。

如何完成的

一、咱们有两个行列,一个更新ui,一个缓存音讯

二、咱们还要守时器,要轮询的检查使命

三、咱们还要有行列进入的进口

四、咱们也需求有处理行列的当地

五、咱们还要有最后处理结果的方案

六、还得需求一个清除的功用,要不怎么回收呢

举一个栗子

假定咱们有个需求,收到音讯后,弹出一个横幅告诉,弹出横幅告诉后几秒后消失,可是在这几秒中,会收到多条音讯,你需求将这多条音讯兼并展现,听起来是不是很耳熟,就是说咱们聊天音讯,一条音讯展现一条内容,多条音讯做兼并。
现在看实践代码:如下所示

/**
 * 堆栈音讯协助类
 * */
object QueuePushHelper {
    /**
     * 通过type修正监听状况
     * */
    private var type = false
    private var queuePushInterface: QueuePushInterface? = null
    fun setQueuePushInterface(queuePushInterface: QueuePushInterface) {
        this.queuePushInterface = queuePushInterface
    }
    /**
     * 缓存一切音讯
     */
    private var cacheGiftList: LinkedList<QueuePushBean> =
        LinkedList<QueuePushBean>()
    /**
     * 用于更新界面音讯的行列
     */
    private var uiMsgList: LinkedList<QueuePushBean> =
        LinkedList<QueuePushBean>()
    /**
     * 守时器
     */
    private var msgTimer = Executors.newScheduledThreadPool(2)
    private lateinit var futures: ScheduledFuture<*>
    /**
     * 音讯加入行列
     */
    @JvmStatic
    @Synchronized
    fun onMsgReceived(customMsg: QueuePushBean) {
        cacheGiftList.offer(customMsg)
    }
    /**
     *  清空行列
     * */
    fun clearQueue() {
        if (cacheGiftList.size > 0) {
            cacheGiftList.clear()
        }
        if (uiMsgList.size > 0) {
            uiMsgList.clear()
        }
        updateStatus(true)
    }
    /**
     * 修正行列状况
     * */
    fun updateStatus(status: Boolean) {
        type = status
    }
    /**
     * 敞开守时使命,数据清空
     * */
    @JvmStatic
    fun startReceiveMsg() {
        if (cacheGiftList.size > 0) {
            cacheGiftList.clear()
        }
        if (uiMsgList.size > 0) {
            uiMsgList.clear()
        }
        updateStatus(true)
        futures = msgTimer.scheduleAtFixedRate(
            TimerTask(),
            0,
            500,
            TimeUnit.MILLISECONDS
        )
    }
    /**
     * 结束守时使命,数据清空
     * ### 退出登录,需求清楚
     * */
    fun stopReceiveMsg() {
        updateStatus(false)
        if (cacheGiftList.size > 0) {
            cacheGiftList.clear()
        }
        if (uiMsgList.size > 0) {
            uiMsgList.clear()
        }
        if (::futures.isInitialized) {
            futures.cancel(true)
        }
        msgTimer.shutdown()
    }
    /**
     * 守时使命
     * */
    class TimerTask : Runnable {
        override fun run() {
            try {
                synchronized(cacheGiftList) {
                    if (type) {
                        if (cacheGiftList.isNullOrEmpty()) {
                            return
                        }
                        uiMsgList.clear()
                        uiMsgList.offer(cacheGiftList.pollLast())
                        uiMsgList.poll()?.let {
                            if (cacheGiftList.size > 1) {
                                it.type = true
                            }
                            //poll一个用户信息,且从剩下集合中过滤出第一个不同名字的用户
                            queuePushInterface?.handleMessage(
                                it,
                                cacheGiftList.firstOrNull { its->
                                    it.msg.fromNick !=its.msg.fromNick
                                }?.msg?.fromNick,
                                cacheGiftList.size + 1 // 因为poll了一个 所以数量加1
                            )
                        }
                        cacheGiftList.clear()
                    }
                }
            } catch (e: Exception) {
                Log.d("QueuePushHelper", "run: e $e")
            }
        }
    }
    interface QueuePushInterface {
        fun handleMessage(item: QueuePushBean, name: String?, msgCount: Int)
    }
}

我代码都贴出来了,我们一看就知道 这个也太简略了。就不多解说了,假如还需求解说就留言吧,祝我们事事安全