【问题标题】:How to perform a haptic feedback in Jetpack Compose如何在 Jetpack Compose 中执行触觉反馈
【发布时间】:2021-07-11 06:26:23
【问题描述】:

使用 jetpack compose,对于 clickevent 如何执行触觉反馈。我是jetpack compose的新手。 这是我尝试过的-

val hapticFeedback = LocalHapticFeedback

@Composable
fun Tab() {
    Row() {
        Icon(imageVector = icon, contentDescription = text)
        if (selected) {
            // i tried both the following ways, none are working. 
            hapticFeedback.current.performHapticFeedback(
                HapticFeedbackType(10)
            )
            hapticFeedback.current.performHapticFeedback(HapticFeedbackType.TextHandleMove)
....
            Spacer(Modifier.width(12.dp))
            Text(text.uppercase(Locale.getDefault()))
        }
    }
}

我可以在文本被选中时看到它,但没有得到细微的振动反馈。

【问题讨论】:

    标签: android-jetpack-compose haptic-feedback


    【解决方案1】:

    在 Compose 的 rc-01 版本中,您只能使用两种类型的触觉反馈:HapticFeedbackType.LongPressHapticFeedbackType.TextHandleMove

    val haptic = LocalHapticFeedback.current
    val context = LocalContext.current
    Row(
        Modifier.clickable {
            haptic.performHapticFeedback(HapticFeedbackType.LongPress)
        }
    )
    

    【讨论】:

    • HapticFeedbackType.TextHandleMove ,在执行可点击操作时似乎不起作用,只有 HapticFeedbackType.LongPress 有效。
    【解决方案2】:

    目前(撰写 UI 1.1.0-beta03)仅支持 LongPressTextHandleMove

    val haptic = LocalHapticFeedback.current
    Button(onClick = {
        haptic.performHapticFeedback(HapticFeedbackType.LongPress)
    }) { ... }
    

    正如@nglauber 的回答所说。

    我猜是因为 Compose Desktop 支持多平台。

    但是,还有另一种方法,如果您使用的是 Android 并且不需要 Compose Desktop 兼容性,那么使用它相当容易:

    val view = LocalView.current
    Button(onClick = {
        view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP)
    }) { ... }
    

    HapticFeedbackConstants 类有 a lot of constants

    【讨论】:

      【解决方案3】:

      Modifier.clickable {...}内添加反馈逻辑应用于Row

      【讨论】:

        【解决方案4】:

        在我的手机(以及我测试过的其他设备)上,LongPressTextHandleMove 都不会使手机振动。

        在迁移到 Compose 之前,我们已经解决了这个问题:

        import android.content.Context
        import android.view.HapticFeedbackConstants
        import android.view.View
        import android.view.accessibility.AccessibilityManager
        
        fun View.vibrate() = reallyPerformHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
        fun View.vibrateStrong() = reallyPerformHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
        
        private fun View.reallyPerformHapticFeedback(feedbackConstant: Int) {
            if (context.isTouchExplorationEnabled()) {
                // Don't mess with a blind person's vibrations
                return
            }
            // Either this needs to be set to true, or android:hapticFeedbackEnabled="true" needs to be set in XML
            isHapticFeedbackEnabled = true
        
            // Most of the constants are off by default: for example, clicking on a button doesn't cause the phone to vibrate anymore
            // if we still want to access this vibration, we'll have to ignore the global settings on that.
            performHapticFeedback(feedbackConstant, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
        }
        
        private fun Context.isTouchExplorationEnabled(): Boolean {
            // can be null during unit tests
            val accessibilityManager = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager?
            return accessibilityManager?.isTouchExplorationEnabled ?: false
        }
        

        现在我们仍然需要使用这段代码并从 Compose 中访问它,就像在 Daniele Segato's answer 中一样:

        @Composable
        fun VibratingButton() {
            val view = LocalView.current
            Button(onClick = {
                view.vibrate()
            }) { ... }
        }
        
        

        【讨论】:

          猜你喜欢
          • 2017-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多