LoginSignup
4
2

More than 1 year has passed since last update.

【Android】RecyclerViewでアイテムが中心に来るように自動スクロール

Last updated at Posted at 2022-09-22

はじめに

RecyclerViewでのアイテム一覧画面で、スワイプ後に指を離した時、アイテムが中心に来るように自動スクロールする処理を作成。
ViewPager2でも作成可能だが、今回はRecyclerViewで作成。

方法

アイテムが中心に来るように自動スクロールするには、LinearSnapHelperを使用。
両端のオフセットは、ItemDecorationを使用。
中心アイテムが変更されたことを検知するためには、OnScrollListenerを使用。
プログラムのポイントとしては、MainActivity.kt内の処理。

まず、カードビューのレイアウト。テキストビューを配置。

list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:tools="http://schemas.android.com/tools"
	android:id="@+id/text"
	android:layout_width="280dp"
	android:layout_height="160dp"
	android:layout_marginHorizontal="8dp"
	android:background="@color/main"
	android:gravity="center"
	android:textColor="@color/white"
	android:textSize="28sp"
	tools:text="1"/>

メイン画面。RcyclerViewを配置。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:background="@color/white">

	<androidx.recyclerview.widget.RecyclerView
		android:id="@+id/recycler_view"
		android:layout_width="0dp"
		android:layout_height="160dp"
		android:orientation="horizontal"
		app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent"
		tools:listitem="@layout/list_item"/>
</androidx.constraintlayout.widget.ConstraintLayout>

アダプタークラス。selectItemIndexで中心アイテムのインデックスを指定し、背景色の変更を行う。

ItemAdapter.kt
class ItemAdapter : RecyclerView.Adapter<ItemAdapter.ViewHolder>() {

	var selectItemIndex = 0
		set(value) {
			field = value
			notifyDataSetChanged()
		}

	class ViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root)

	override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))

	override fun onBindViewHolder(holder: ViewHolder, position: Int) {
		holder.binding.text.text = position.toString()

		val color = if (position == selectItemIndex) R.color.main else R.color.sub
		holder.binding.text.setBackgroundColor(ContextCompat.getColor(holder.binding.root.context, color))
	}

	override fun getItemCount() = 10
}

メイン画面の処理。中心自動スクロールや両端のオフセット設定、スクロール検知を行う。

MainActivity.kt
class MainActivity : AppCompatActivity() {

	/** ViewBinding */
	private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(binding.root)

		binding.recyclerView.adapter = ItemAdapter()

		//両端のオフセット設定
		binding.recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
			override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
				val margin = (parent.width - view.layoutParams.width) / 2
				val position = parent.getChildAdapterPosition(view)
				if (position == 0) outRect.left = margin
				if (position == state.itemCount - 1) outRect.right = margin
			}
		})

		//アイテムが中心に来るように自動スクロール
		val snapHelper = LinearSnapHelper()
		snapHelper.attachToRecyclerView(binding.recyclerView)

		//中心アイテム色変更
		binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
			override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
				super.onScrollStateChanged(recyclerView, newState)
				val view = snapHelper.findSnapView(recyclerView.layoutManager)
				if (view != null) {
					val position = recyclerView.getChildAdapterPosition(view)
					if (position >= 0) (recyclerView.adapter as? ItemAdapter)?.selectItemIndex = position
				}
			}
		})
	}
}

参考サイト

関連記事

ViewPager2を使用

4
2
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
4
2