Jetpack Compose でスクロール可能な項目を画面の中央にスナップする方法
からSnapper
移行しましたSnapFlingBehavior
前回は、Android アプリ開発における一般的な使用例、つまりフリング ジェスチャの後にスクロール可能な項目を画面の中央にスナップする方法について説明しました。
Jetpack Compose でこれを実現するには、以前にアーカイブされた「Snapper」ライブラリを使用します。Snapper は、公式フレームワークがまだサポートしていない場合に、スクロール可能なレイアウトでスナップ動作を実装するためのシームレスなソリューションを提供します。その記事を見逃した場合は、ここで読むことができます。
それ以来、Jetpack Compose は成長してきました。嬉しいことに、以前 Snapper ライブラリを使用して実装していた機能が、Jetpack Compose で正式にサポートされ、 が導入されましたSnapFlingBehavior
。この新しいクラスは、動的コンテンツを含むスクロール可能なリスト内の項目を中央に配置するための、より包括的かつ効率的なソリューションを提供します。
この記事では、以前の記事で扱った問題を再検討し、Snapper ライブラリの使用から正式にサポートされているライブラリに移行する方法を示しますSnapFlingBehavior
。まず 2 つのアプローチの主な違いについて説明し、それを Jetpack Compose プロジェクトに実装するためのステップバイステップのガイドを提供しますSnapFlingBehavior
。
SnapFlingBehavior に変換する
簡単にまとめるために、Snapper で実装するコア機能を見てみましょう。このライブラリを使用すると、フリング ジェスチャの後にアイテムを画面の中央にスナップする動的なスクロール可能なリストを作成できます。Jetpack Compose にこのユースケースを正式に実装する機能がない場合、これは優れた解決策となります。
導入によりSnapFlingBehavior
、Jetpack Compose の公式 API を使用してこのスナップ動作を実装できるようになりました。Snapper ライブラリよりもSnapFlingBehavior
優れた柔軟性とカスタマイズ オプションを提供します。ショート/スクロール スナップとロング/フリング スナップを区別するパラメーターを
SnapFlingBehavior
使用して、項目を指定の位置にスナップするクラス。shortSnapVelocityThreshold
さらに、highVelocityAnimationSpec
、 、lowVelocityAnimationSpec
など、さまざまな状況に応じたさまざまなアニメーション仕様が提供されますsnapAnimationSpec
。
次に、SnapFlingBehavior を活用して、以前に Snapper ライブラリを使用して実現したのと同じ機能を実現する方法を見てみましょう。
以前のユースケースを再考する
Snapper ライブラリに関する前回の記事では、動的リストの例を使用しました。
@Composable
fun MainContent(
placeholderItems: List<String>
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
text = "Example Horizontal LazyRow"
)
LazyRow(
modifier = Modifier.fillMaxWidth(),
contentPadding = PaddingValues(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
items(items = placeholderItems) {
itemMessage: String ->
PlaceholderCard(itemMessage)
}
}
}
}
実際の効果は次のとおりです。
次のコード スニペットに示すように、Snapper を使用してフリング動作を実現できます。
val lazyListState: LazyListState = rememberLazyListState()
val layoutInfo: LazyListSnapperLayoutInfo = rememberLazyListSnapperLayoutInfo(lazyListState)
LazyRow(
modifier = Modifier.fillMaxWidth(),
state = lazyListState,
flingBehavior = rememberSnapperFlingBehavior(lazyListState),
contentPadding = PaddingValues(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
items(items = placeholderItems) {
itemMessage: String ->
PlaceholderCard(itemMessage)
}
}
SnapFlingBehavior を使用する
ただし、フリング ジェスチャを実行した後、表示されているアイテムが画面の中央までスクロールするようにするために、外部ライブラリに依存する必要はなくなりました。代わりに、以前に説明した内容を活用できますSnapFlingBehavior
。
次のコード スニペットは、 SnapFlingBehavior
enabled をMainContent
。
@Composable
fun MainContent(
placeholderItems: List<String>
) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
text = "Example Horizontal LazyRow"
)
val listState: LazyListState = rememberLazyListState()
LazyRow(
modifier = Modifier.fillMaxWidth(),
contentPadding = PaddingValues(horizontal = 32.dp),
verticalAlignment = Alignment.CenterVertically,
state = listState,
flingBehavior = rememberSnapFlingBehavior(listState)
) {
items(placeholderItems) {
item: String ->
PlaceholderCard(itemMessage = item)
}
}
}
}
まず、コンポーネントの状態を保存および管理できるrememberLazyListState()
関数を使用してコンポーネントを作成します。LazyListState
LazyRow
val listState: LazyListState = rememberLazyListState()
次に、次のプロパティを持つLazyRow
コンポーネント。
modifier = Modifier.fillMaxWidth()
: が画面の幅全体LazyRow
に広がっていることを。contentPadding = PaddingValues(horizontal = 32.dp)
:LazyRow
の内側に。verticalAlignment = Alignment.CenterVertically
: 項目を垂直方向の中央にLazyRow
配置します。state = listState
: 以前に定義したLazyListState
をLazyRow
の状態に設定します。flingBehavior = rememberSnapFlingBehavior(listState)
: を指定すると、フリング ジェスチャの後にリスト内の項目が中央にスナップし、最終的に目的の動作が実現されるように、に割り当てますlistState
。SnapFlingBehavior
LazyRow
最終的な効果は以下の通りです。
結論は
この記事では、Jetpack Compose でスクロール可能なアイテムを画面の中央にスナップする問題を再検討し、Snapper ライブラリの使用から正式にサポートされているライブラリに切り替えましたSnapFlingBehavior
。
最初に、ジェスチャー スワイプ後に項目を画面の中央に自動的にスナップする動的でスクロール可能なリストを以前どのように実装したかを確認しました。続いて、公式ソリューションを使用した同じ方法について説明しました。最終的に、コードの長さの違いはそれほど大きくなく、移行プロセスは非常に簡単であることがわかりました。