Make FlatViewGroup implement ReactCompoundViewGroup interface
Summary: In FlatViewGroup, we flatten some react nodes into parent while mounting others into child Views. This is causing touch events being dispatched to wrong targets because child Views are \"stealing\" touch events from flattened Views. To fix the issue, implement ReactCompoundViewGroup to provide information about both virtual and non-virtual nodes. Reviewed By: ahmedre Differential Revision: D3018054
This commit is contained in:
parent
b52928c484
commit
89cf5c49b9
|
@ -29,7 +29,7 @@ import com.facebook.react.common.SystemClock;
|
|||
import com.facebook.react.touch.OnInterceptTouchEventListener;
|
||||
import com.facebook.react.touch.ReactInterceptingViewGroup;
|
||||
import com.facebook.react.uimanager.PointerEvents;
|
||||
import com.facebook.react.uimanager.ReactCompoundView;
|
||||
import com.facebook.react.uimanager.ReactCompoundViewGroup;
|
||||
import com.facebook.react.uimanager.ReactPointerEventsView;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.views.image.ImageLoadEvent;
|
||||
|
@ -39,7 +39,7 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
* array of DrawCommands, executing them one by one.
|
||||
*/
|
||||
/* package */ final class FlatViewGroup extends ViewGroup
|
||||
implements ReactInterceptingViewGroup, ReactCompoundView, ReactPointerEventsView {
|
||||
implements ReactInterceptingViewGroup, ReactCompoundViewGroup, ReactPointerEventsView {
|
||||
/**
|
||||
* Helper class that allows AttachDetachListener to invalidate the hosting View.
|
||||
*/
|
||||
|
@ -133,6 +133,16 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean interceptsTouchEvent(float touchX, float touchY) {
|
||||
NodeRegion nodeRegion = anyNodeRegionWithinBounds(touchX, touchY);
|
||||
if (nodeRegion != null) {
|
||||
return nodeRegion.mIsVirtual;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
|
@ -257,6 +267,10 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (interceptsTouchEvent(ev.getX(), ev.getY())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mOnInterceptTouchEventListener != null &&
|
||||
mOnInterceptTouchEventListener.onInterceptTouchEvent(this, ev)) {
|
||||
return true;
|
||||
|
@ -411,7 +425,7 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
LAYOUT_REQUESTS.clear();
|
||||
}
|
||||
|
||||
private NodeRegion virtualNodeRegionWithinBounds(float touchX, float touchY) {
|
||||
private @Nullable NodeRegion virtualNodeRegionWithinBounds(float touchX, float touchY) {
|
||||
for (int i = mNodeRegions.length - 1; i >= 0; --i) {
|
||||
NodeRegion nodeRegion = mNodeRegions[i];
|
||||
if (!nodeRegion.mIsVirtual) {
|
||||
|
@ -426,6 +440,17 @@ import com.facebook.react.views.image.ImageLoadEvent;
|
|||
return null;
|
||||
}
|
||||
|
||||
private @Nullable NodeRegion anyNodeRegionWithinBounds(float touchX, float touchY) {
|
||||
for (int i = mNodeRegions.length - 1; i >= 0; --i) {
|
||||
NodeRegion nodeRegion = mNodeRegions[i];
|
||||
if (nodeRegion.withinBounds(touchX, touchY)) {
|
||||
return nodeRegion;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private View ensureViewHasNoParent(View view) {
|
||||
ViewParent oldParent = view.getParent();
|
||||
if (oldParent != null) {
|
||||
|
|
Loading…
Reference in New Issue