我有一个大致定义为
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 /行为
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中,onInterceptTouchEvent中检测到了触摸事件(在布局中的任何位置),但在onTouchEvent中没有检测到。TouchBehavior.onTouchEvent()在TouchBehavior附加到MyView1时从未被调用,而不管onInterceptTouchEvent和onTouchEvent是在MyView1上定义的还是两者之一。
从Android的管理ViewGroup中的Touch事件中,我的理解是,当在ViewGroup中检测到触摸事件时,会调用onInterceptTouchEvent(),并且它可以返回true以指示它将截获/使用事件,而不是传播到其子事件。在我的示例中,MyView1.onInterceptTouchEvent使用它的超类逻辑返回false,这意味着它可以供自己或子用户使用。但是,由于没有调用MyView1.onTouchEvent,所以我认为事件是由子视图使用的。
话虽如此,也许这个问题对其他人来说是显而易见的,但它让我认为事件是由一个子视图或它的一个侦听器消耗的,因此寻找了一种方法来确定该MotionEvent的最终使用者。MyView1和MyView2各有8-10个子视图(布局/小部件/等),在结构上非常不同。
那么,如何确定哪个View消耗了某些输入事件(MotionEvent)?
发布于 2017-05-31 15:01:55
你可以这样做。在ViewGroup.dispatchTouchEvent方法中设置一个断点。如果您使用的是SDK 25,那么可以使用第2266行。使用触摸事件的是child View。
您还可以在那里配置断点,以便IDE将登录到控制台。
发布于 2017-05-31 11:07:23
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类OnTouch方法中,您应该返回false。
如果返回true,则只有onInterceptTouchEvent方法会触发。如果您返回false,onInterceptTouchEvent和onTouchEvent都会触发
https://stackoverflow.com/questions/44138192
复制相似问题