我找到了
onClick
和 onLongClick
甚至 onPress
的监听器,但是没有像 buttonDown
和 buttonUp
或 onPress
和 onRelease
这样的事件/监听器。
我错过了什么吗?我当前的用例是,当用户按下按钮时,我会增加计数,当用户释放按钮时,我会减少计数。但总的来说,我希望用户按下按钮后就开始发生一些事情,并在用户释放按钮时停止。 (举个现实生活中的例子,看看 Facebook Messenger 如何录制视频,按住按钮即可开始,松开按钮后视频就会停止。
我在 Android 上使用 Jetpack Compose。
您可以使用
InteractionSource.collectIsPressedAsState
来了解按钮是否被按下。
您可以添加副作用来了解按钮何时被释放。
类似:
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
var currentStateTxt by remember { mutableStateOf("Not Pressed") }
var currentCount by remember { mutableStateOf(0) }
if (isPressed){
//Pressed
currentStateTxt = "Pressed"
currentCount += 1
//Use if + DisposableEffect to wait for the press action is completed
DisposableEffect(Unit) {
onDispose {
//released
currentStateTxt = "Released"
}
}
}
Button(onClick={},
interactionSource = interactionSource
){
Text("Current state = $currentStateTxt")
Text("Count = $currentCount")
}
Modifier.pointerInput(Unit) {
detectTapGestures(
onPress = {
//start
val released = try {
tryAwaitRelease()
} catch (c: CancellationException) {
false
}
if (released) {
//ACTION_UP
} else {
//CANCELED
}
},
onTap = {
// onTap
},
onDoubleTap = {
//onDoubleTap
},
onLongPress = {
//onLongPress
}
)
}
这些代码可能对你有帮助
var isPressed by remember {
mutableStateOf(false)
}
.pointerInput(Unit) {
detectTapGestures(
onPress = {
try {
isPressed = true
isPlaying = true
sampleSong.start()
awaitRelease()
}
finally {
isPressed = false
isPlaying = false
sampleSong.pause()
}
使用.pointerInput修饰符:
.pointerInput(Unit) {
forEachGesture {
awaitPointerEventScope {
awaitFirstDown()
//onPress actions here
do {
val event = awaitPointerEvent()
//Track other pointer evenst, like Drag etc...
} while (event.changes.any { it.pressed })
//onRelease actions here
}
}
}
.pointerInput(Unit) {
awaitEachGesture {
awaitFirstDown().also {
it.consume()
Timber
.tag("click_events")
.d("Action down")
}
val up = waitForUpOrCancellation()
// up is null when the pointer exits its bounds
up?.consume()
Timber
.tag("click_events")
.d("Action up or the the pointer exited its bounds")
}
如果您想在按下按钮时以特定的时间间隔执行操作,您可以使用以下代码(改编自Gabriele的答案)。此示例会在长按时自动增加值。
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
var currentStateTxt by remember { mutableStateOf("Not Pressed") }
var currentCount by remember { mutableStateOf(0) }
val coroutineScope = rememberCoroutineScope()
if (isPressed) {
var job: Job? = null
LaunchedEffect(Unit) {
currentStateTxt = "Pressed"
currentCount += 1
job = coroutineScope.launch {
delay(500)
while (isActive) { // Coroutine is only cancellable at this line
currentCount += 1
delay(150)
}
}
}
DisposableEffect(Unit) {
onDispose {
job?.cancel()
currentStateTxt = "Released"
}
}
}
Button(
onClick = {},
interactionSource = interactionSource
) {
Text("Current state = $currentStateTxt, count = $currentCount")
}
我认为你在按钮上使用触摸监听器,它可以轻松检测按钮触摸或未触摸示例
override fun onTouchEvent(e: MotionEvent): Boolean {
val x: Float = e.x
val y: Float = e.y
when (e.action) {
MotionEvent.ACTION_MOVE -> {
var dx: Float = x - previousX
var dy: Float = y - previousY
// reverse direction of rotation above the mid-line
if (y > height / 2) {
dx *= -1
}
// reverse direction of rotation to left of the mid-line
if (x < width / 2) {
dy *= -1
}
renderer.angle += (dx + dy) * TOUCH_SCALE_FACTOR
requestRender()
}
}
previousX = x
previousY = y
return true
}
此链接中触摸监听器的更多信息Android触摸监听器