Skip to content

Commit

Permalink
Fix issue #8 where the touch goes not through TouchThroughView
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Hoss authored and Simon Hoss committed Dec 22, 2017
1 parent e7e6a06 commit aaeb029
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 10 deletions.
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,43 @@ eg.

Have a look at the demo in the example directory if you need more help.

## Issues
Currently we are working through an issue at #8 with Android devices on that latest version of React Native not properly passing through touch events.
## Android Installation
For Android you have to do the normal react-native link. Also you have to change MainActivity inside you project. See example below

```java
package com.reactnativetouchthroughviewexample;

import com.facebook.react.ReactActivity;
import android.view.MotionEvent;
import com.rome2rio.android.reactnativetouchthroughview.TouchThroughTouchHandlerInterface;
import com.rome2rio.android.reactnativetouchthroughview.TouchThroughTouchHandler;

public class MainActivity extends ReactActivity implements TouchThroughTouchHandlerInterface {

private TouchThroughTouchHandler touchThroughTouchHandler = new TouchThroughTouchHandler();

/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "reactnativetouchthroughviewexample";
}

public TouchThroughTouchHandler getTouchThroughTouchHandler() {
return touchThroughTouchHandler;
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
touchThroughTouchHandler.handleTouchEvent(ev);

return super.dispatchTouchEvent(ev);
}
}

```

## Credits
Brought to you by the team at [Rome2rio](https://www.rome2rio.com). Find out how to join our team at <https://www.rome2rio.com/careers/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.rome2rio.android.reactnativetouchthroughview;

import android.view.MotionEvent;

public class TouchThroughTouchHandler {

private TouchThroughTouchHandlerListener listener = null;

public void setListener(TouchThroughTouchHandlerListener listener) {
this.listener = listener;
}

public void handleTouchEvent(MotionEvent ev) {
if (listener != null) {
listener.handleTouch(ev);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.rome2rio.android.reactnativetouchthroughview;

import android.view.MotionEvent;

public interface TouchThroughTouchHandlerInterface {
public TouchThroughTouchHandler getTouchThroughTouchHandler();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.rome2rio.android.reactnativetouchthroughview;

import android.view.MotionEvent;

public abstract class TouchThroughTouchHandlerListener {
abstract void handleTouch(MotionEvent ev);
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
package com.rome2rio.android.reactnativetouchthroughview;

import com.facebook.react.views.view.ReactViewGroup;
import com.facebook.react.touch.ReactHitSlopView;
import com.facebook.react.bridge.ReactContext;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.graphics.Rect;
import android.view.ViewGroup;

public class TouchThroughWrapper extends ReactViewGroup {
public TouchThroughWrapper(Context context) {
public class TouchThroughWrapper extends ReactViewGroup implements ReactHitSlopView {
private boolean lastTouchWasNotValid = false;

public TouchThroughWrapper(ReactContext context) {
super(context);
this.setActivityListener(context);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Recursively find out if an absolute x/y position is hitting a child view and stop event
// propagation if a hit is found.
return this.isTouchingTouchThroughView(this, Math.round(event.getX()), Math.round(event.getY()));
return lastTouchWasNotValid;
}

private void setActivityListener(ReactContext context) {
Activity activity = context.getCurrentActivity();
final ViewGroup viewGroup = this;

if (activity instanceof TouchThroughTouchHandlerInterface) {
TouchThroughTouchHandlerInterface handlerInterface = (TouchThroughTouchHandlerInterface) activity;
handlerInterface.getTouchThroughTouchHandler().setListener(new TouchThroughTouchHandlerListener() {
@Override
void handleTouch(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
int y = (int) ev.getY();
System.out.println("" + y);
lastTouchWasNotValid = isTouchingTouchThroughView(viewGroup, (int) ev.getX(), (int) ev.getY());
}
}
});
} else {
throw new RuntimeException("TouchThroughTouchHandlerInterface was not set on app activity");
}
}

// Recursively find out if an absolute x/y position is hitting a child view and stop event
// propagation if a hit is found.
private boolean isTouchingTouchThroughView(ViewGroup viewgroup, int x, int y) {
boolean isTouchingTouchThroughView = false;

for(int i = 0; i < viewgroup.getChildCount(); i++) {
for (int i = 0; i < viewgroup.getChildCount(); i++) {
View child = viewgroup.getChildAt(i);

boolean isViewGroup = child instanceof ViewGroup;
Expand All @@ -42,8 +70,7 @@ private boolean isTouchingTouchThroughView(ViewGroup viewgroup, int x, int y) {
Rect bounds = new Rect(childX, childY, childX + child.getWidth(), childY + child.getHeight());

isTouchingTouchThroughView = bounds.contains(x, y);
}
else if (isViewGroup) {
} else if (isViewGroup) {
isTouchingTouchThroughView = this.isTouchingTouchThroughView((ViewGroup) child, x, y);
}

Expand All @@ -60,4 +87,12 @@ public boolean onTouchEvent(MotionEvent event) {
// Pass through touch events to layer behind.
return false;
}

//If the touch was not on the list make the slop rect small so react-native dont use this view as responder
public Rect getHitSlopRect() {
if (lastTouchWasNotValid) {
return new Rect(-1000, -1000, -1000, -1000);
}
return new Rect(0, 0, 0, 0);
}
}

0 comments on commit aaeb029

Please sign in to comment.