5
0

More than 1 year has passed since last update.

Jetpack Compose で Haptics に対応する

Last updated at Posted at 2022-09-30

Haptics とは

利用者に力、振動、動きなどを与えることで皮膚感覚フィードバックを得るテクノロジーのことで、ことAndroidにおいては触覚による刺激生成に貢献するハードウェアとソフトウェアの機能を指します。

Androidでの Haptics Framework

UX原則として以下の3パターンが推進されています。

hapticsSAC12_1.png

1. Buzzy

ポケベルやガラケー時代に利用されていた低品質ながらも電力効率の高いERMブザーベースのバイブレーション

2. Clear

非連続の状態変化(Power On/Offやプロセス中のバイナリ変化) をサポート
クリアなHapticsは1つのInput Eventに対して1つのHapticなど単一のエンティティとして生成されます

hapticsSAC14_1.png

3. Rich

単一のインパルスベースの効果を超える成長中のカテゴリ。Androidとしては高度な構成可能性と細かい粒度での調整可能性を備えたリッチなHaptics をサポートすることを目指している。

hapticsSAC15_1.gif

Sample

振動エフェクトとして3つのカテゴリが用意されているためカテゴリごとのアクションを含んだButtonを作成します。

HapticsRoute.kt
@Composable
private fun PredefinedEffectsButton(
    label: String,
    effect: Int,
    application: Application
) {
    val vibrator = ContextCompat.getSystemService(application, Vibrator::class.java)!!
    TextButton(
        onClick = {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                vibrator.vibrate(VibrationEffect.createPredefined(effect))
            }
        },
    ) {
        Text(label)
    }
}

@Composable
private fun HapticFeedbackConstantsButton(
    label: String,
    effect: Int,
) {
    val view = LocalView.current
    TextButton(
        onClick = {
            view.performHapticFeedback(effect)
        },
    ) {
        Text(label)
    }
}

@Composable
private fun CompositionPrimitivesButton(
    label: String,
    effect: Int,
    application: Application
) {
    val vibrator = ContextCompat.getSystemService(application, Vibrator::class.java)!!
    TextButton(
        onClick = {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                vibrator.vibrate(
                    VibrationEffect.startComposition()
                        .addPrimitive(effect)
                        .compose()
                )
            }
        },
    ) {
        Text(label)
    }
}

それぞれのカテゴリは以下をご参照ください。

  1. VibrationEffect#createPredefined
  2. View#performHapticFeedback
  3. VibrationEffect.Composition

最後にScreenの定義を行います。

HapticsRoute.kt
@Composable
fun HapticsRoute(
    application: Application
) {
    Screen(
        homeUiState = viewModel.homeUiState, onButtonClicked = viewModel::onButtonClicked,
        onSnackbarMessage = viewModel::onSnackbarMessage, scrollState = viewModel.scrollState,
    )
}

@Composable
private fun Screen(application: Application) {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // PREDEFINED_EFFECTS
        PredefinedEffectsButton(
            label = "EFFECT_TICK",
            effect = VibrationEffect.EFFECT_TICK,
            application = application
        )

        // HAPTIC_FEEDBACK_CONSTANTS
        HapticFeedbackConstantsButton(
            label = "CONFIRM",
            effect = HapticFeedbackConstants.CONFIRM
        )

        // COMPOSITION_PRIMITIVES
        CompositionPrimitivesButton(
            label = "EFFECT_TICK",
            effect = VibrationEffect.Composition.PRIMITIVE_LOW_TICK,
            application = application
        )
    }
}

その他カテゴリごとに何種類もEffectが用意されているのですぐに利用できます。

最後に

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0