确定触摸输入消费者
Determine Touch Input Consumer
我有一个观点大致定义为
class MyView1 extends LinearLayout {
// for debugging, not actually needed
@Override public boolean onTouchEvent(MotionEvent event) {
Log.d(getClass().getSimpleName(), "");
}
// also for debugging, not actually needed
@Override public boolean onInterceptTouchEvent(MotionEvent ev){
boolean handle = super.onInterceptTouchEvent(ev);
Log.v(getClass().getSimpleName(), "handle?=" + handle);
return handle;
}
}
}
和 TouchListener/Behavior 为
class TouchBehavior implements View.OnTouchListener {
View myView; // assigned in ctor
public void attach() { myView.setOnTouchListener( this ); }
@Override public boolean onTouch(View v, MotionEvent event) {
Log.d(getClass().getSimpleName(), "log just for detection");
// actual logic...
}
附加到 MyView1
(通过日志记录验证)。此逻辑适用于另一个视图 MyView2
(也扩展了 LinearLayout
)但不适用于 MyView1
,原因我尚未确定。在 MyView1
中,touch-events(点击布局中的任意位置)在 onInterceptTouchEvent
中检测到,但在 onTouchEvent
中检测不到。当 TouchBehavior
附加到 MyView1
时,永远不会调用 TouchBehavior.onTouchEvent()
,无论 onInterceptTouchEvent
和 onTouchEvent
中的一个或两个是否在 MyView1
上定义。
来自 Android 文档的 Managing Touch Events in a ViewGroup 我的理解是 onInterceptTouchEvent()
在 ViewGroup
中检测到触摸事件时被调用并且它可以 return true
表示它将 intercept/consume 事件而不传播到其 children。在我的示例中,MyView1.onInterceptTouchEvent
使用其 super-class 逻辑是 returning false,这意味着它可以单独使用或 children。但是,由于未调用 MyView1.onTouchEvent
我认为该事件由 child sub-view.
消耗
说了这么多,也许这个问题对其他人来说是显而易见的,但它让我认为事件被 child sub-view 或其听众之一消耗了,所以搜索了一种方法来确定 MotionEvent
的最终消费者。 MyView1
和 MyView2
各有 8-10 个子视图 (layout/widget/etc),并且在结构上有很大不同。
那么我如何确定哪个 View
消耗了一些输入事件 (MotionEvent
)?
public class Myview extends LinearLayout {
public Myview(Context context) {
super(context);
}
public Myview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Myview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(getContext(), "onTouchEvent", Toast.LENGTH_SHORT).show();
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Toast.makeText(getContext(), "onInterceptTouchEvent", Toast.LENGTH_SHORT).show();
boolean handle = super.onInterceptTouchEvent(ev);
return handle;
}
}
在上面的 TouchBehavior class OnTouch
方法中你应该 return false.
如果你 return true 只有 onInterceptTouchEvent
方法会触发。如果你 return false onInterceptTouchEvent
和 onTouchEvent
都会触发
您可以按照以下步骤操作。在 ViewGroup.dispatchTouchEvent
方法处设置断点。如果您使用的是 SDK 25,那么您可以使用第 2266 行。child
View
那里是消费触摸事件的人。
您还可以在那里配置断点,以便 IDE 将登录到控制台。
我有一个观点大致定义为
class MyView1 extends LinearLayout {
// for debugging, not actually needed
@Override public boolean onTouchEvent(MotionEvent event) {
Log.d(getClass().getSimpleName(), "");
}
// also for debugging, not actually needed
@Override public boolean onInterceptTouchEvent(MotionEvent ev){
boolean handle = super.onInterceptTouchEvent(ev);
Log.v(getClass().getSimpleName(), "handle?=" + handle);
return handle;
}
}
}
和 TouchListener/Behavior 为
class TouchBehavior implements View.OnTouchListener {
View myView; // assigned in ctor
public void attach() { myView.setOnTouchListener( this ); }
@Override public boolean onTouch(View v, MotionEvent event) {
Log.d(getClass().getSimpleName(), "log just for detection");
// actual logic...
}
附加到 MyView1
(通过日志记录验证)。此逻辑适用于另一个视图 MyView2
(也扩展了 LinearLayout
)但不适用于 MyView1
,原因我尚未确定。在 MyView1
中,touch-events(点击布局中的任意位置)在 onInterceptTouchEvent
中检测到,但在 onTouchEvent
中检测不到。当 TouchBehavior
附加到 MyView1
时,永远不会调用 TouchBehavior.onTouchEvent()
,无论 onInterceptTouchEvent
和 onTouchEvent
中的一个或两个是否在 MyView1
上定义。
来自 Android 文档的 Managing Touch Events in a ViewGroup 我的理解是 onInterceptTouchEvent()
在 ViewGroup
中检测到触摸事件时被调用并且它可以 return true
表示它将 intercept/consume 事件而不传播到其 children。在我的示例中,MyView1.onInterceptTouchEvent
使用其 super-class 逻辑是 returning false,这意味着它可以单独使用或 children。但是,由于未调用 MyView1.onTouchEvent
我认为该事件由 child sub-view.
说了这么多,也许这个问题对其他人来说是显而易见的,但它让我认为事件被 child sub-view 或其听众之一消耗了,所以搜索了一种方法来确定 MotionEvent
的最终消费者。 MyView1
和 MyView2
各有 8-10 个子视图 (layout/widget/etc),并且在结构上有很大不同。
那么我如何确定哪个 View
消耗了一些输入事件 (MotionEvent
)?
public class Myview extends LinearLayout {
public Myview(Context context) {
super(context);
}
public Myview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Myview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Toast.makeText(getContext(), "onTouchEvent", Toast.LENGTH_SHORT).show();
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Toast.makeText(getContext(), "onInterceptTouchEvent", Toast.LENGTH_SHORT).show();
boolean handle = super.onInterceptTouchEvent(ev);
return handle;
}
}
在上面的 TouchBehavior class OnTouch
方法中你应该 return false.
如果你 return true 只有 onInterceptTouchEvent
方法会触发。如果你 return false onInterceptTouchEvent
和 onTouchEvent
都会触发
您可以按照以下步骤操作。在 ViewGroup.dispatchTouchEvent
方法处设置断点。如果您使用的是 SDK 25,那么您可以使用第 2266 行。child
View
那里是消费触摸事件的人。
您还可以在那里配置断点,以便 IDE 将登录到控制台。