LoginSignup
6
2

More than 3 years have passed since last update.

【Android】ViewPager2でサイズが変わるカルーセル作成

Last updated at Posted at 2021-02-16

dp定義

dimen.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="offset">10dp</dimen>
    <dimen name="margin">50dp</dimen>
    <dimen name="total_margin">60dp</dimen>
</resources>

offset: 隣のアイテムを見せる長さ
margin: アイテム間の距離
total_marginoffset+margin

レイアウト作成

ViewPager2を配置するメインレイアウトの作成。

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"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/view_pager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

次に、アイテムレイアウトの作成。横をtotal_margin分だけマージンを取る。

view_item.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:layout_marginStart="@dimen/total_margin"
    android:layout_marginEnd="@dimen/total_margin">

    <View
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:background="@color/teal_200"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="1" />

</androidx.constraintlayout.widget.ConstraintLayout>

Adapterの作成

ViewPager用Adapterの作成

ItemAdapter.kt
class ItemAdapter(private val items: List<String>) :
    RecyclerView.Adapter<ItemAdapter.ViewHolder>() {

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

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.binding.text.text = items[position]
    }

    override fun getItemCount() = items.size
}

処理作成

最後に、処理の作成。sizeRateを変更することで、サイドに表示されるアイテムの大きさが変わります。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)

        binding.viewPager.adapter = ItemAdapter(listOf("1", "2", "3"))
        binding.viewPager.offscreenPageLimit = 2
        binding.viewPager.setPageTransformer { page, position ->
            val sizeRate = 0.5F

            val margin = resources.getDimensionPixelOffset(R.dimen.margin)
            val offset = resources.getDimensionPixelOffset(R.dimen.offset)
            val itemWidth = binding.viewPager.width - (margin + offset) * 2
            page.translationX =
                -position * (2 * offset + margin + (1 - sizeRate) * itemWidth / 2)
            val scale = 1 - (kotlin.math.abs(position) * (1 - sizeRate))
            page.scaleX = scale
            page.scaleY = scale
        }
        setContentView(binding.root)
    }
}

参考資料: https://satoshun.github.io/2019/08/viewpager2-like-a-carousel/

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