Skip to content
This repository has been archived by the owner on Nov 14, 2018. It is now read-only.

Add View onTouch extensions #524

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions api/current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,17 @@ package androidx.core.view {
public final class ViewKt {
ctor public ViewKt();
method @RequiresApi(16) public static void announceForAccessibility(android.view.View, @StringRes int resource);
method public static void doOnActionCancel(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> action);
method public static void doOnActionDown(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> action);
method public static void doOnActionMove(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> action);
method public static void doOnActionOutside(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> action);
method public static void doOnActionPointerDown(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> action);
method public static void doOnActionPointerUp(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> action);
method public static void doOnActionUp(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> action);
method public static void doOnLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
method public static void doOnNextLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
method public static void doOnPreDraw(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
method public static void doOnTouch(android.view.View, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> onActionDown = "{}", kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> onActionUp = "{}", kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> onActionMove = "{}", kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> onActionCancel = "{}", kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> onActionOutside = "{}", kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> onActionPointerDown = "{}", kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> onActionPointerUp = "{}");
method public static boolean isGone(android.view.View);
method public static boolean isInvisible(android.view.View);
method public static boolean isVisible(android.view.View);
Expand Down
81 changes: 81 additions & 0 deletions src/androidTest/java/androidx/core/view/ViewTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ package androidx.core.view

import android.graphics.Bitmap
import android.graphics.Color
import android.os.SystemClock
import android.support.test.InstrumentationRegistry
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
Expand All @@ -37,6 +39,15 @@ class ViewTest {
private val context = InstrumentationRegistry.getContext()
private val view = View(context)

private fun obtainMotionEvent(eventType: Int) = MotionEvent.obtain(
SystemClock.uptimeMillis(),
SystemClock.uptimeMillis() + 100,
eventType,
0f,
0f,
0
)

@Test
fun doOnNextLayout() {
var calls = 0
Expand Down Expand Up @@ -270,4 +281,74 @@ class ViewTest {
val resolvedText = context.getText(R.string.text)
assertEquals(testView.announcement, resolvedText)
}

@Test fun doOnActionDown() {
var called = false
view.doOnActionDown {
called = true
}

view.dispatchTouchEvent(obtainMotionEvent(MotionEvent.ACTION_DOWN))
assertTrue(called)
}

@Test fun doOnActionUp() {
var called = false
view.doOnActionUp {
called = true
}

view.dispatchTouchEvent(obtainMotionEvent(MotionEvent.ACTION_UP))
assertTrue(called)
}

@Test fun doOnActionMove() {
var called = false
view.doOnActionMove {
called = true
}

view.dispatchTouchEvent(obtainMotionEvent(MotionEvent.ACTION_MOVE))
assertTrue(called)
}

@Test fun doOnActionCancel() {
var called = false
view.doOnActionCancel {
called = true
}

view.dispatchTouchEvent(obtainMotionEvent(MotionEvent.ACTION_CANCEL))
assertTrue(called)
}

@Test fun doOnActionOutside() {
var called = false
view.doOnActionOutside {
called = true
}

view.dispatchTouchEvent(obtainMotionEvent(MotionEvent.ACTION_OUTSIDE))
assertTrue(called)
}

@Test fun doOnActionPointerDown() {
var called = false
view.doOnActionPointerDown {
called = true
}

view.dispatchTouchEvent(obtainMotionEvent(MotionEvent.ACTION_POINTER_DOWN))
assertTrue(called)
}

@Test fun doOnActionPointerUp() {
var called = false
view.doOnActionPointerUp {
called = true
}

view.dispatchTouchEvent(obtainMotionEvent(MotionEvent.ACTION_POINTER_UP))
assertTrue(called)
}
}
94 changes: 94 additions & 0 deletions src/main/java/androidx/core/view/View.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ import android.support.annotation.Px
import android.support.annotation.RequiresApi
import android.support.annotation.StringRes
import android.support.v4.view.ViewCompat
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_CANCEL
import android.view.MotionEvent.ACTION_DOWN
import android.view.MotionEvent.ACTION_MOVE
import android.view.MotionEvent.ACTION_OUTSIDE
import android.view.MotionEvent.ACTION_POINTER_DOWN
import android.view.MotionEvent.ACTION_POINTER_UP
import android.view.MotionEvent.ACTION_UP
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
Expand Down Expand Up @@ -289,3 +297,89 @@ inline fun <reified T : ViewGroup.LayoutParams> View.updateLayoutParams(block: T
block(params)
layoutParams = params
}

/**
* Add an [action] which will be invoked when a pressed gesture has started
*
* @see View.setOnTouchListener
*/
inline fun View.doOnActionDown(crossinline action: (event: MotionEvent) -> Unit) =
doOnTouch(onActionDown = action)

/**
* Add an [action] which will be invoked when a pressed gesture has finished
*
* @see View.setOnTouchListener
*/
inline fun View.doOnActionUp(crossinline action: (event: MotionEvent) -> Unit) =
doOnTouch(onActionUp = action)

/**
* Add an [action] which will be invoked when a change has happened during a press gesture
*
* @see View.setOnTouchListener
*/
inline fun View.doOnActionMove(crossinline action: (event: MotionEvent) -> Unit) =
doOnTouch(onActionMove = action)

/**
* Add an [action] which will be invoked when the current gesture has been aborted
*
* @see View.setOnTouchListener
*/
inline fun View.doOnActionCancel(crossinline action: (event: MotionEvent) -> Unit) =
doOnTouch(onActionCancel = action)

/**
* Add an [action] which will be invoked when a movement has happened outside of the
* normal bounds of the UI element. This does not provide a full gesture,
* but only the initial location of the movement/touch.
*
* @see View.setOnTouchListener
*/
inline fun View.doOnActionOutside(crossinline action: (event: MotionEvent) -> Unit) =
doOnTouch(onActionOutside = action)

/**
* Add an [action] which will be invoked when a non-primary pointer has gone down.
* Use [event.actionIndex] to retrieve the index of the pointer that changed.
*
* @see View.setOnTouchListener
*/
inline fun View.doOnActionPointerDown(crossinline action: (event: MotionEvent) -> Unit) =
doOnTouch(onActionPointerDown = action)

/**
* Add an [action] which will be invoked when a non-primary pointer has gone up.
* Use [event.actionIndex] to retrieve the index of the pointer that changed.
*
* @see View.setOnTouchListener
*/
inline fun View.doOnActionPointerUp(crossinline action: (event: MotionEvent) -> Unit) =
doOnTouch(onActionPointerUp = action)

/**
* Add a touch listener to this View using the provided actions.
*/
inline fun View.doOnTouch(
crossinline onActionDown: (event: MotionEvent) -> Unit = {},
crossinline onActionUp: (event: MotionEvent) -> Unit = {},
crossinline onActionMove: (event: MotionEvent) -> Unit = {},
crossinline onActionCancel: (event: MotionEvent) -> Unit = {},
crossinline onActionOutside: (event: MotionEvent) -> Unit = {},
crossinline onActionPointerDown: (event: MotionEvent) -> Unit = {},
crossinline onActionPointerUp: (event: MotionEvent) -> Unit = {}
) {
setOnTouchListener { _, event ->
when (event.action) {
ACTION_DOWN -> onActionDown(event)
ACTION_UP -> onActionUp(event)
ACTION_MOVE -> onActionMove(event)
ACTION_CANCEL -> onActionCancel(event)
ACTION_OUTSIDE -> onActionOutside(event)
ACTION_POINTER_DOWN -> onActionPointerDown(event)
ACTION_POINTER_UP -> onActionPointerUp(event)
}
return@setOnTouchListener true
}
}