0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ドラムロールUIに触覚フィードバックを導入してUX向上する!

Posted at

はじめに

Jetpack Composeでの触覚フィードバック(Haptic)の情報がまだ少なかったので、LazyColumnを使った実装例をまとめました。
意外と簡単に試せるので、ぜひ端末で触って体験してみてください!

対象

  • Jetpack Composeを業務で使っているAndroidエンジニア
  • LazyColumnでドラムロール風UIやスナップスクロールを設計したい
  • 触覚フィードバック(Haptic)APIの適用例を知りたい方

実装

ポイント

選択状態が変わったときだけHapticを発火する

  • LazyListState.firstVisibleItemIndexを監視
  • selectedIndexが変わったときだけSegmentTick
  • LaunchedEffectとsnapshotFlowを組み合わせて差分を検出

Pixel系では動作確認できましたが、端末によっては動作しない場合があります。

コード

端末を繋いでAndroidStudioでRun Previewすれば体験できるサンプルです

@Preview(showBackground = true)
@Composable
fun HapticDrumrollPreview() {
    val listState = rememberLazyListState()
    val haptic = LocalHapticFeedback.current
    var selectedIndex by remember { mutableIntStateOf(listState.firstVisibleItemIndex) }
    
    LaunchedEffect(listState) {
        snapshotFlow { listState.firstVisibleItemIndex }
            .distinctUntilChanged()
            .collect { newIndex ->
                if (newIndex != selectedIndex) {
                    haptic.performHapticFeedback(HapticFeedbackType.SegmentTick)
                    selectedIndex = newIndex
                }
            }
    }
    
    LazyColumn(
        state = listState,
        modifier = Modifier
            .fillMaxWidth()
            .height(200.dp),
        contentPadding = PaddingValues(vertical = 80.dp)
    ) {
        items(20) { index ->
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 8.dp),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    "項目 $index",
                    fontSize = 20.sp,
                    color = if (index == selectedIndex) Color.Blue else Color.Unspecified
                )
            }
        }
    }
}

応用のアイデア

触覚フィードバックは「値が一段階進む」ようなUIと相性が良いです。
今回の仕組みを応用すると、例えば次のようなケースで利用できます。

  • ドラムロール風の時刻ピッカー
    → 1分ごとに「コトッ」とフィードバックが返ると直感的
  • 音量や速度などの段階選択
    → 数値が一段階変わるごとに軽く震えると操作感が増す
  • スロットマシン風UI
    → リールが止まる瞬間に「ガチッ」と響くとゲーム感が出る
  • 縦方向のナビゲーションセレクター
    → リストを切り替えるときに切れ目がわかりやすくなる

触覚フィードバックの種類

Compose では様々な種類の HapticFeedback が用意されています。
大きく分けると次のような用途があります。

  • 操作の確定や切り替え
    • Confirm
    • ToggleOn / ToggleOff
    • VirtualKey
  • 操作の中断やエラー
    • Reject
    • GestureEnd
  • 連続的な操作の節目
    • SegmentTick(今回使用)
    • SegmentFrequentTick
    • TextHandleMove
  • 一般的な操作
    • ContextClick
    • KeyboardTap(API 33 以降)
    • LongPress
    • GestureThresholdActivate

特に今回使った SegmentTick は「スクロールで項目が切り替わる瞬間」に最適です。
他のタイプも UI に合わせて使い分けると、操作感がぐっと良くなります。

参考文献

0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?