7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NTTテクノクロスAdvent Calendar 2023

Day 12

Jetpack ComposeのHorizontalPager上でLazyColumnを動かす時に、横スワイプの効き具合を調整する方法

Last updated at Posted at 2023-12-11

はじめに

この記事はNTTテクノクロス Advent Calendar 2023の12日目です。

こんにちは、NTTテクノクロスの笠松と申します。 普段はAndroid/iOSアプリの開発に携わっています。

Jetpack ComposeはAndroidのネイティブUIを構築するための最新のツールキットです。2021年7月28日にこのツールキットが安定版リリースとなっており、使用しているチームも多いのではないでしょうか。

この記事ではこのJetpack Composeに関するTipsを紹介します。とてもニッチなケースですが、ご覧ください。

本記事で紹介するTips

本記事では以下のように縦スワイプと横スワイプが混在するケースを考えます。

  • HorizontalPagerにより横スワイプで画面を切り替えることができる
  • LazyColumnにより縦スワイプでアイテムの一覧を見ることができる

capture.png

この時に、縦スワイプが優先されて、横スワイプによるページ切り替えがスムーズにできない時があります。この記事では縦スワイプと横スワイプの効き具合を調整して、両スワイプの体験を改善する方法を紹介します。

touchSlopについて

Jetpack Composeではどれくらいスワイプしたらスクロールとみなすかを示すtouchSlopという値が用意されています。

Jetpack Compose

package androidx.compose.ui.platform

class AndroidViewConfiguration(
    private val viewConfiguration: android.view.ViewConfiguration
) : ViewConfiguration {
    //...
    override val touchSlop: Float
        get() = viewConfiguration.scaledTouchSlop.toFloat()
}

今回はLazyColumntouchSlopを調整して、縦スクロールの効き具合を調整します。

Jetpack ComposeにおけるtouchSlopの指定方法

この記事ではtouchSlopCompositionLocalを使って指定します。
CompositionLocalはComposeのUIツリーの特定のノードで値を設定し、その値を暗黙的に子孫のノードでも使用できるようにする仕組みです。

具体的には以下のソースコードのようにCompositionLocalProviderを使用して、LocalViewConfigurationCustomViewConfigurationを指定します。

CompositionLocalProvider(
    LocalViewConfiguration provides CustomViewConfiguration(
        viewConfiguration = AndroidViewConfiguration(
            android.view.ViewConfiguration.get(LocalContext.current),
        ),
        touchSlopRatio = 2.5f,
    )
) {
    LazyColumn(
        modifier = Modifier.fillMaxSize()
    ) {
        items(200) {
            //コンテンツ
        }
    }
}

CustomViewConfigurationは基本的にはデフォルトの動作と同様にAndroidViewConfigurationを使用し、touchSlopのみoverrideします。

data class CustomViewConfiguration(
    private val viewConfiguration: ViewConfiguration,
    private val touchSlopRatio: Float,
) : ViewConfiguration by viewConfiguration {
    override val touchSlop: Float = viewConfiguration.touchSlop * touchSlopRatio
}

touchSlopに大きい値を指定すると、縦スワイプと判定されるまでのスワイプの量が大きくなるため、HorizontalPagerの横スワイプが優先されるようになります。

終わりに

この記事で紹介したtouchSlopによる調整はHorizontalPagerの代わりにAndroid ViewViewPager2を使用している場合でも機能します。また、純粋にスワイプの感度の調整としても有効です。

前述の通り、CompositionLocalの設定はComposeのUIツリーの子孫のノードでも有効になる点に注意してください。

シリーズ1の13日目は@tana0610さんが「UnrealEngine」について書いてくださいます。

明日もぜひご覧ください:-)

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?