
回复
扩展事件分发机制 dispatchTouchEvent -> onInterceptTouchEvent -> onTouchEvent,并实现了requestDisallowInterceptTouchEvent方法。
public class ViewParent extends DirectionalLayout implements Component.TouchEventListener, ViewGroup
setTouchEventListener(this);
@Override
public boolean onTouchEvent(Component component, TouchEvent event) {
return DispatchHelper.dispatch(component, event);
}
ViewGroupHelper impl = new ViewGroupHelper();
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
impl.requestDisallowInterceptTouchEvent(disallowIntercept);
}
@Override
public boolean onInterceptTouchEvent(TouchEvent ev) {
return false;
}
@Override
public boolean dispatchTouchEvent(TouchEvent event) {
return impl.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(TouchEvent event) {
return false;
}
@Override
public boolean isConsumed() {
return impl.isConsumed();
}
public class ViewChild extends ScrollView implements Component.TouchEventListener, View
setTouchEventListener(this);
@Override
public boolean onTouchEvent(Component component, TouchEvent event) {
return DispatchHelper.dispatch(component, event);
}
4、转发ViewGroup接口内的dispatchTouchEvent、isConsumed方法至ViewHelper实现,并在onTouchEvent内实现具体分发逻辑
ViewHelper impl = new ViewHelper();
@Override
public boolean dispatchTouchEvent(TouchEvent event) {
return impl.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(TouchEvent event) {
return true;
}
@Override
public boolean isConsumed() {
return impl.isConsumed();
}
Component需要父控件不拦截事件,可以调用DispatchHelper的requestDisallowInterceptTouchEvent方法
DispatchHelper.requestDisallowInterceptTouchEvent(this, false);
// postRequestDisallowInterceptTouchEvent会通过EventHandler将函数延迟执行
// 避免在构造函数中调用requestDisallowInterceptTouchEvent时,获取ComponentParent为空的情况
DispatchHelper.postRequestDisallowInterceptTouchEvent(this, false);
接着打印每个函数的日志,并且尝试修改父控件的onInterceptTouchEvent、onTouchEvent,以及子控件的onTouchEvent的值,并查看日志结果。
也可以再多尝试几层ViewGroup实现,来实现更复杂的效果。
由于ohos的事件传递是冒泡形式,即事件会先到目标控件内,如果目标控件不消耗事件,则冒泡到父控件内。而安卓的事件则是先传递到父控件,再经过分发,传递到目标控件内。
因此DispatchHelper的主要作用就是查找视图树内所有实现了View或ViewGroup的控件,并调用顶层控件的dispatchTouchEvent函数向下分发事件。并过滤掉由于事件冒泡,而传递过来的重复事件。
ViewHelper、ViewGroupHelper则主要实现了安卓的View、ViewGroup中dispatchTouchEvent函数的逻辑。