Android 如何实现触摸生成的ImageView跟随手指移动
实现方案
核心修改逻辑
- 在Activity中声明全局的ImageView成员变量,存储
ACTION_DOWN时创建的图片实例,解决ACTION_MOVE事件中无法访问局部变量的问题 - 将onTouchListener的返回值改为
true,告知触摸事件分发机制你要消费本次触摸序列,才能持续收到ACTION_MOVE、ACTION_UP等后续事件 - 在
ACTION_MOVE分支中,实时更新ImageView的布局边距实现位置跟随
完整修改后代码
class MainActivity : AppCompatActivity() { // 全局存储当前拖动的ImageView private var currentIv: ImageView? = null @SuppressLint("ClickableViewAccessibility", "UseCompatLoadingForDrawables") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val rr = findViewById<RelativeLayout>(R.id.relative_layout) rr.setOnTouchListener { v, event -> when(event.action) { MotionEvent.ACTION_DOWN -> { val x = event.x.toInt() val y = event.y.toInt() val lp = RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ) lp.setMargins(x, y, 0, 0) val iv = ImageView(applicationContext) iv.layoutParams = lp iv.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_blur_circular_24)) (v as ViewGroup).addView(iv) // 赋值给全局变量 currentIv = iv } MotionEvent.ACTION_MOVE -> { currentIv?.let { iv -> val lp = iv.layoutParams as RelativeLayout.LayoutParams // 直接更新边距即可刷新位置 lp.leftMargin = event.x.toInt() lp.topMargin = event.y.toInt() iv.layoutParams = lp // 可选优化:让图片中心跟随手指,替换上面两行即可 // lp.leftMargin = event.x.toInt() - iv.width / 2 // lp.topMargin = event.y.toInt() - iv.height / 2 } } // 可选:抬起/取消事件时释放引用 MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { currentIv = null } } // 必须返回true,才能接收后续触摸事件 true } } }
内容的提问来源于stack exchange,提问作者Bence Blaskovics
相关产品推荐
相关产品推荐

