본문 바로가기
Android & Kotlin/Android

viewpager2 이미지 자동 스크롤 (recyclerview활용)

by 말린밴댕이_공부 2022. 12. 28.
반응형

기존 viewpager에서 viewpager2를 사용하는 이유

  • Orientation 추가 →Horiaontal Paging에서 VerticalPaging도 지원이 가능해짐
  • RTI페이징 가능
  • notifyDatasetChanged를 이용한 동적 페이지 가능

필요한 것들 및 개념 정리

  • image를 출력해주는 xml
  • 이미지를 출력해주는 viewpager
  • 배열에 저장할 image모음
  • recyclerview

우선 우리가 활용하는 리사이클러뷰와 개념이 아주 매우 흡사하다.

리사이클러뷰에 대한 이해를 하였다면 viewpager2를 문제없이 구상할 수 있다.

또한 이미지가 넘어가는것은 따로 진행해주기 때문에 thread를 활용한다는것을 기억해야한다.

우선 활용할 layout .xml에 추가를 viewpager를 추가해준다.

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewpager2_Main_Image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

그리고 main_list_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">

    <ImageView
        android:id="@+id/imageView5"
        android:layout_width="0dp"
        android:layout_height="150dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/pic_recommend1" />
</androidx.constraintlayout.widget.ConstraintLayout>
class MainImageAdapter(var imageSlideMember : List<Main_Image_Data>) : RecyclerView.Adapter<MainImageAdapter.imageViewHolder>()  {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : imageViewHolder {
        val binding = MainImageListBinding.inflate(LayoutInflater.from(parent.context),parent,false)

        return imageViewHolder(binding)
    }

    override fun onBindViewHolder(holder: imageViewHolder, position: Int) {
        holder.bind(imageSlideMember[position])
    }

    override fun getItemCount(): Int {
        return imageSlideMember.size
    }

    inner class imageViewHolder(val binding : MainImageListBinding) : RecyclerView.ViewHolder(binding.root){
        fun bind(mainImagedata: Main_Image_Data){
            //Glide를 활용하여 진행!
            Glide.with(itemView).load(mainImagedata.image).into(binding.ivImageSlide)
        }
    }

}

imageAdapter 코드

기존에 리사이클러뷰를 공부를 했다면 똑같은 방식으로 진행을 하면 된다.

여기서 Glide를 활용하여 이미지를 처리해주었습니다.

class Main_Image_Data(
    var image : Int
)

이미지만 구성을 해보는 예제를 한것이기 때문에 dataclass에 이미지만 선언을 하고 다음에 필요한것이 있다면 또한 추가를 하면 된다.

이제 뷰페이저를 활용할 위치의 코드를 보게되면

//이미지 슬라이드 리스트를 테스트 하기 위해 배열로 추가가
   private val imageSlideList = mutableListOf<Main_Image_Data>().apply{
        add(Main_Image_Data(R.drawable.pic_recommend1))
        add(Main_Image_Data(R.drawable.pic_food1))
        add(Main_Image_Data(R.drawable.pic_food2))
        add(Main_Image_Data(R.drawable.pic_food3))
        add(Main_Image_Data(R.drawable.pic_review))
    }
    // 현재 페이지
    var currentPage = 0

우선 위에 테스트를 하기 위해 어댑터의 배열로 선언을 하여 이미지를 추가를 진행해줬습니다.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // 이미지 어댑터 연결
        val viewPager2 = binding.viewpager2MainImage
        binding.viewpager2MainImage.adapter = MainImageAdapter(imageSlideList)
        binding.viewpager2MainImage.orientation = ViewPager2.ORIENTATION_HORIZONTAL
        val child = binding.viewpager2MainImage.getChildAt(0)
        

        // 이미지 쓰레드 시작
        val thread = Thread(PagerRunnable())
        thread.start()
    }

그러고 이제 제가 구현한 프래그먼트에서 adapter를 설정하여 orientation을 수평으로 설정해주었습니다.

///여기서부터 이미지 슬라이드 구현
   val handler = Handler(Looper.getMainLooper()){
        setPage()
        true
    }

    //이미지 슬라이드 구현부분
    inner class PagerRunnable:Runnable{
        override fun run() {
            //2초를 sleep -> handler메세지 전달
            //runnable class 는 interface임
            while(true){
                try{
                    Thread.sleep(2000)
                    handler.sendEmptyMessage(0)
                } catch (e : InterruptedException){
                    Log.d("thread","thread문제")
                }
            }
        }
    }

    fun setPage(){
        if(currentPage == imageSlideList.size)
            currentPage = 0
        binding.viewpager2MainImage.setCurrentItem(currentPage,true)
        currentPage += 1
    }

자동 스크롤을 넘어가기 하기 위해서는 thread를 활용하여 진행하여야합니다.

Handler를 통해서 thread를 통제하게 되는데 여기서 페이지가 마지막으로 가게 된다면 첫번째 페이지로 바뀌게 되도록 하는 형식으로 진행하였습니다.

 

 

이미지는 테스트용도로 진행을 하였고 앱은 망고플레이트 클론코딩을 통한 공부를 위해 진행중에 필요한 개념 

viewpager2 + recyclerview를 활용하여 진행하였습니다.

반응형

댓글