はじめに
この記事はNTTテクノクロス Advent Calendar 2023の12日目です。
こんにちは、NTTテクノクロスの笠松と申します。 普段はAndroid/iOSアプリの開発に携わっています。
Jetpack Compose
はAndroidのネイティブUIを構築するための最新のツールキットです。2021年7月28日にこのツールキットが安定版リリースとなっており、使用しているチームも多いのではないでしょうか。
この記事ではこのJetpack Compose
に関するTipsを紹介します。とてもニッチなケースですが、ご覧ください。
本記事で紹介するTips
本記事では以下のように縦スワイプと横スワイプが混在するケースを考えます。
-
HorizontalPager
により横スワイプで画面を切り替えることができる -
LazyColumn
により縦スワイプでアイテムの一覧を見ることができる
この時に、縦スワイプが優先されて、横スワイプによるページ切り替えがスムーズにできない時があります。この記事では縦スワイプと横スワイプの効き具合を調整して、両スワイプの体験を改善する方法を紹介します。
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()
}
今回はLazyColumn
のtouchSlop
を調整して、縦スクロールの効き具合を調整します。
Jetpack ComposeにおけるtouchSlopの指定方法
この記事ではtouchSlop
をCompositionLocal
を使って指定します。
CompositionLocal
はComposeのUIツリーの特定のノードで値を設定し、その値を暗黙的に子孫のノードでも使用できるようにする仕組みです。
具体的には以下のソースコードのようにCompositionLocalProvider
を使用して、LocalViewConfiguration
にCustomViewConfiguration
を指定します。
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 View
のViewPager2
を使用している場合でも機能します。また、純粋にスワイプの感度の調整としても有効です。
前述の通り、CompositionLocal
の設定はComposeのUIツリーの子孫のノードでも有効になる点に注意してください。
シリーズ1の13日目は@tana0610さんが「UnrealEngine」について書いてくださいます。
明日もぜひご覧ください:-)