You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中点击按钮每秒刷新自定义View并支持启停如何实现?

实现方案

方案一:Kotlin协程(推荐,无需手动处理内存泄漏)

Kotlin协程配合lifecycleScope可以自动跟随页面生命周期销毁,不会出现任务泄漏问题。
先在Activity/Fragment中声明全局变量:

// 刷新状态标记
private var isRefreshing = false
// 持有刷新协程任务
private var refreshJob: Job? = null
// 你的两个自定义View实例,需先和xml布局绑定
private lateinit var view1: myView1
private lateinit var view2: myView2

按钮点击逻辑:

// 替换为你的按钮id
controlBtn.setOnClickListener {
    isRefreshing = !isRefreshing
    if (isRefreshing) {
        refreshJob = lifecycleScope.launch {
            while (isActive) {
                // 主线程调用invalidate触发onDraw
                view1.invalidate()
                view2.invalidate()
                // 间隔1秒
                delay(1000L)
            }
        }
    } else {
        // 终止协程,停止刷新
        refreshJob?.cancel()
        refreshJob = null
    }
}

方案二:Handler + Runnable(兼容低版本逻辑)

如果需要兼容不支持协程的旧项目,可以用主线程Handler实现定时任务。
声明全局变量:

// 绑定主线程Looper,确保任务在主线程执行
private val refreshHandler = Handler(Looper.getMainLooper())
private val refreshTask = object : Runnable {
    override fun run() {
        view1.invalidate()
        view2.invalidate()
        // 间隔1秒后再次执行任务
        refreshHandler.postDelayed(this, 1000L)
    }
}
private var isRefreshing = false

按钮点击逻辑:

controlBtn.setOnClickListener {
    isRefreshing = !isRefreshing
    if (isRefreshing) {
        // 立即启动第一次刷新
        refreshHandler.post(refreshTask)
    } else {
        // 移除待执行任务,终止循环
        refreshHandler.removeCallbacks(refreshTask)
    }
}

页面销毁时主动清理任务避免内存泄漏:

override fun onDestroy() {
    super.onDestroy()
    refreshHandler.removeCallbacks(refreshTask)
}

之前invalidate不生效的常见原因

  • 调用invalidate的代码运行在子线程:Android仅允许主线程更新UI,子线程调用不会触发重绘,甚至会抛出异常
  • 自定义View宽高为0:如果布局中自定义View的宽高计算结果为0,onDraw方法不会被回调,可先设置固定宽高验证
  • 调用invalidate的对象不是当前页面渲染的View实例:确认你调用方法的View和布局绑定的是同一个实例

内容的提问来源于stack exchange,提问作者Klaudia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 21:45:08