Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix overlay touch detection #6372

Merged
merged 3 commits into from
Jul 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}

flavorDimensions "RNN.reactNativeVersion"
productFlavors {
Expand Down Expand Up @@ -154,7 +157,7 @@ allprojects { p ->
}

dependencies {
implementation "androidx.core:core-ktx:1.1.0"
implementation "androidx.core:core-ktx:1.3.0"
implementation "org.jetbrains.kotlin:$kotlinStdlib:$kotlinVersion"

implementation 'androidx.appcompat:appcompat:1.1.0'
Expand All @@ -174,5 +177,7 @@ dependencies {
testImplementation 'org.assertj:assertj-core:3.8.0'
testImplementation 'com.squareup.assertj:assertj-android:1.1.1'
testImplementation 'org.mockito:mockito-core:2.28.2'

testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlinVersion"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.reactnativenavigation.utils

import android.graphics.Rect
import android.view.MotionEvent
import android.view.View

val hitRect = Rect()

fun MotionEvent.coordinatesInsideView(view: View?): Boolean {
view ?: return false
view.getHitRect(hitRect)
return hitRect.contains(x.toInt(), y.toInt())
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.reactnativenavigation.views.touch

import android.view.MotionEvent
import androidx.annotation.VisibleForTesting
import com.reactnativenavigation.options.params.Bool
import com.reactnativenavigation.options.params.NullBool
import com.reactnativenavigation.react.ReactView
import com.reactnativenavigation.utils.coordinatesInsideView
import com.reactnativenavigation.views.component.ComponentLayout

open class OverlayTouchDelegate(private val component: ComponentLayout, private val reactView: ReactView) {
var interceptTouchOutside: Bool = NullBool()

fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return when (interceptTouchOutside.hasValue() && event.actionMasked == MotionEvent.ACTION_DOWN) {
true -> handleDown(event)
false -> component.superOnInterceptTouchEvent(event)
}
}

@VisibleForTesting
open fun handleDown(event: MotionEvent) = when (event.coordinatesInsideView(reactView.getChildAt(0))) {
true -> component.superOnInterceptTouchEvent(event)
false -> interceptTouchOutside.isFalse
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.reactnativenavigation.utils

import android.app.Activity
import android.view.MotionEvent
import android.view.View
import android.view.View.MeasureSpec
import android.widget.FrameLayout
import androidx.core.view.marginTop
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import com.reactnativenavigation.BaseTest
import org.assertj.core.api.Java6Assertions.assertThat
import org.junit.Test

class MotionEventTest : BaseTest() {
private lateinit var uut: MotionEvent
private lateinit var activity: Activity
private lateinit var parent: FrameLayout
private val x = 173f
private val y = 249f

override fun beforeEach() {
uut = MotionEvent.obtain(0L, 0, 0, x, y, 0)
activity = newActivity()
parent = FrameLayout(activity)
activity.setContentView(parent)
}

@Test
fun coordinatesInsideView() {
val v: View = mock()
assertThat(uut.coordinatesInsideView(v)).isFalse()
}

@Test
fun coordinatesInsideView_inside() {
val view = View(activity)
parent.addView(view, 200, 300)
assertThat(uut.coordinatesInsideView(view)).isTrue()
}

@Test
fun coordinatesInsideView_outside() {
val view = View(activity)
parent.addView(view, 200, 300)
view.top = (y + 1).toInt()
assertThat(uut.coordinatesInsideView(view)).isFalse()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,31 @@
import android.view.MotionEvent;

import com.reactnativenavigation.BaseTest;
import com.reactnativenavigation.mocks.SimpleOverlay;
import com.reactnativenavigation.options.params.Bool;
import com.reactnativenavigation.react.ReactView;
import com.reactnativenavigation.views.component.ComponentLayout;
import com.reactnativenavigation.views.touch.OverlayTouchDelegate;

import org.junit.Test;
import org.mockito.Mockito;

import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

public class TouchDelegateTest extends BaseTest {
public class OverlayTouchDelegateTest extends BaseTest {
private OverlayTouchDelegate uut;
private final int x = 10;
private final int y = 10;
private final MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, x, y, 0);
private final MotionEvent upEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, x, y, 0);
private SimpleOverlay reactView;
private ComponentLayout component;

@Override
public void beforeEach() {
super.beforeEach();
reactView = spy(new SimpleOverlay(newActivity()));
component = Mockito.mock(ComponentLayout.class);
ReactView reactView = mock(ReactView.class);
component = mock(ComponentLayout.class);
uut = spy(new OverlayTouchDelegate(component, reactView));
}

Expand Down
2 changes: 1 addition & 1 deletion playground/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

buildscript {
ext {
kotlinVersion = "1.3.61"
kotlinVersion = "1.3.72"
RNNKotlinVersion = kotlinVersion
detoxKotlinVersion = kotlinVersion
}
Expand Down
10 changes: 8 additions & 2 deletions playground/src/screens/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export default function Toast({ componentId }: NavigationComponentProps) {

return (
<View style={styles.root}>
<TouchableOpacity testID={TOAST_OK_BTN_OUTER} onPress={() => dismiss('Outer button clicked')}>
<TouchableOpacity
style={styles.outerTouchable}
testID={TOAST_OK_BTN_OUTER}
onPress={() => dismiss('Outer button clicked')}
>
<View style={styles.toast}>
<Text style={styles.text}>This a very important message!</Text>
<TouchableOpacity
Expand All @@ -37,11 +41,13 @@ const styles = StyleSheet.create({
flexDirection: 'column-reverse',
backgroundColor: '#3e434aa1',
},
outerTouchable: {
margin: 16,
},
toast: {
elevation: 2,
flexDirection: 'row',
height: 40,
margin: 16,
borderRadius: 20,
backgroundColor: Colors.accent,
alignItems: 'center',
Expand Down