android自定义控件跟随手指移动及view事件分发机制
我们都知道自定义控件流程onmeasure(),onlayout(),ondraw(),那么是不是所有得自定义都要重写这三个方法呐,肯定不是的,onmeasure()只是测量控件大小,onlayout(),测量大小后需要控件显示位置,最后通过ondraw()进行绘制.
言归正算自定义控件让控件跟随手指移动,很明显只需要监听手指移动,来改变控件位置,而不需要去重写其他方法:这里我举一个FloatingActionButton的例子:
//自定义悬浮按钮
class CustomFloatingActionButton(context: Context, attr: AttributeSet) : FloatingActionButton(context, attr) {
var down_x = 0f
var down_y = 0f
// var move_x = 0f
// var move_y = 0f
override fun onTouchEvent(ev: MotionEvent?): Boolean {
when (ev!!.action) {
MotionEvent.ACTION_DOWN -> {
down_x = ev.rawX
down_y = ev.rawY
// move_x = ev.rawX
// move_y = ev.rawY
}
MotionEvent.ACTION_MOVE -> {
layout(
(ev.rawX - down_x + left).toInt(),
(ev.rawY - down_y + top).toInt(),
(ev.rawX - down_x + right).toInt(),
(ev.rawY - down_y + bottom).toInt()
)
down_x = ev.rawX
down_y = ev.rawY
invalidate()
}
MotionEvent.ACTION_UP -> {
// if (abs(down_x - move_x) < 5f && abs(down_y - move_y) <= 5f) {
// performClick()
//// isPressed = true
// return super.onTouchEvent(ev)
// }
}
}
return true//如果返回true,从手指接触屏幕到手指离开屏幕,将不会触发点击事件。
}
}
通过代码我们可以看到,重写ontouchevent()方法,监听手势,通过滑动初始位置来设置控件位置,最后调用invalidate()重新绘制.
写在最后:可以看到我们的ontouchevent()最后返回的是true,根据注解返回true就不会执行onclick事件,这是为什么呐?额这就设计到view的事件分发了,在android中事件分发机制主要在activity,viewgroup,view中,今天我就讲下view的事件分发(子view)
在了解view事件分发时你必须知道三个函数,dispatchTouchevent(),onintercepTouchEvent(),ontouchevent(),然而我们今天讲的view事件分发就不存在onintercepTouchEvent()方法了,这个很好理解一个子view要么处理事件要么不处理事件,根本不存在事件拦截之说,dispatchTouchevent()事件分发,这个函数一般我们都不会重写他,并且都是默认返回super.dispatchTouchevent.内部交给ontouchevent处理.但是如果返回true就表明事件消耗了,不再向下分发,如果返回false就表明此view不消耗此次事件,返回上一级viewgroup处理.
注:如果dispatchTouchevent()返回super.dispatchTouchevent,由于view事件分发顺序是ontouch-ontouchevent-onclick
如果我们view中没用ontouch事件,那么默认返回的return super.ontouch..,默认值就是false,此时才会执行ontouchevent事件,如果设置了ontouch事件并且返回的true,那么就不会执行,ontouchevent更别说什么Onclick了。
那么ontouchevent中默认返回的super.ontouchevent也是false,但是我们可以看他源码是实现了onclick的,(通过源码可看到实现onclick是有一些列条件的).如果ontouchevent返回true就表明消耗此时事件,不向下分发也就是不走onclick方法了.当然我们可以在ontouchevent里面直接调用.performclick(),可以监听onclick事件,流程可能不是那么清晰.但是对于对事件分发有一定基础的应该不难理解
上一篇: jsp_自定义简单标签