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

Android View拖拽不流畅问题求助:附实现代码求优化

拖拽卡顿的优化方案

你的拖拽实现卡顿主要是因为动画框架的冗余开销和不必要的视图操作,以下是针对性优化建议:

核心问题与修复

  1. 放弃用animate()做即时位置更新
    每次ACTION_MOVE调用animate()都会创建新的属性动画实例,哪怕设置duration(0),也会经过动画调度流程,产生额外性能损耗。直接修改View的x、y属性是最直接高效的方式。

  2. 避免重复修改视图可见性
    当前每次ACTION_MOVE都设置clearImg.visibility = View.VISIBLE,会重复触发视图重绘。可以加个标志位,只在第一次移动时设置一次。

  3. 正确处理触摸事件返回值
    返回super.onTouchEvent(event)可能导致事件被父控件拦截或触发额外的事件分发逻辑,应该返回true,明确表示当前控件已处理该触摸事件。

优化后的完整代码

// 新增标志位,记录是否已显示清除图标
private var isClearImgVisible = false

clMain.setOnTouchListener { view, event ->
    when(event.action) {
        MotionEvent.ACTION_DOWN -> {
            dx = view.x - event.rawX
            dy = view.y - event.rawY
        }
        MotionEvent.ACTION_MOVE -> {
            // 仅第一次移动时显示清除图标
            if (!isClearImgVisible) {
                clearImg.visibility = View.VISIBLE
                isClearImgVisible = true
            }
            // 直接设置位置,替代animate()
            view.x = event.rawX + dx
            view.y = event.rawY + dy
        }
        MotionEvent.ACTION_UP -> {
            if(areViewsTouching()){
                clMain.visibility = View.GONE
                saveState(this,false)
            }
            clearImg.visibility = View.GONE
            isClearImgVisible = false
        }
    }
    // 返回true表示当前控件处理了触摸事件
    true
}

进阶优化(若后续扩展需求)

如果之后需要添加边界限制、惯性滑动、拖拽结束平滑过渡等功能,建议使用Android官方提供的ViewDragHelper,它封装了触摸事件的处理逻辑,性能更稳定,也能减少手写代码的bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:42:34