Skip to content

Commit

Permalink
Add ReactCompoundViewGroup interface that allows having both virtual …
Browse files Browse the repository at this point in the history
…and non-virtual (View) children

Summary: In React, ReactCompoundView is supposed to be implemented by a View, but there is no ViewGroup counterpart that allows mixing virual nodes and non-virtual ones (Views) in the same parent. This is needed because TouchTargetHelper always considers child Views when looking for touch target before falling back to View/ReactCompoundView. This works incorrectly for e.g. layout-only / flattened nodes. ReactCompoundViewGroup allow intercepting touch event before it is dispatched to its children. In that sense, ReactCompoundView.reactTagForTouch() is like View.onTouchEvent() whereas ReactCompoundViewGroup.interceptsTouchEvent() is like ViewGroup.onInterceptTouchEvent().

Differential Revision: D3018028

fb-gh-sync-id: d2c70a55afb9ce9823275e7483d72e0ebedf52e4
shipit-source-id: d2c70a55afb9ce9823275e7483d72e0ebedf52e4
  • Loading branch information
korDen authored and Facebook Github Bot 3 committed Mar 8, 2016
1 parent d0a26a7 commit aae521f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
@@ -0,0 +1,24 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

package com.facebook.react.uimanager;

/**
* This interface should be implemented be native ViewGroup subclasses that can represent more
* than a single react node. In that case, virtual and non-virtual (mapping to a View) elements
* can overlap, and TouchTargetHelper may incorrectly dispatch touch event to a wrong element
* because it priorities children over parents.
*/
public interface ReactCompoundViewGroup extends ReactCompoundView {
/**
* Returns true if react node responsible for the touch even is flattened into this ViewGroup.
* Use reactTagForTouch() to get its tag.
*/
boolean interceptsTouchEvent(float touchX, float touchY);
}
Expand Up @@ -209,6 +209,11 @@ private static boolean isTransformedTouchPointInView(

} else if (pointerEvents == PointerEvents.AUTO) {
// Either this view or one of its children is the target
if (view instanceof ReactCompoundViewGroup) {
if (((ReactCompoundViewGroup) view).interceptsTouchEvent(eventCoords[0], eventCoords[1])) {
return view;
}
}
if (view instanceof ViewGroup) {
return findTouchTargetView(eventCoords, (ViewGroup) view);
}
Expand Down

0 comments on commit aae521f

Please sign in to comment.