[Kotlin] 카드뷰 활용한 ViewPager2 + 자동스크롤

호우·2022년 7월 27일
0

코틀린

목록 보기
7/8

이 포스팅에서는 카드뷰를 넣은 ViewPager2 세팅과 자동으로 화면이 넘어가도록 만든 부분을 작성해봤다.

제품 등록할 때 등록되는 정보들은 data class로 정리했습니다.

data class ItemInfoDTO(
    var uid : String? = null, //등록자 uid
    var category: String? = null, //물품 카테고리.
    var sellerId : String? = null, //등록자 닉네임
    var docuid: String? = null, //도큐먼트 uid
    var item_name : String? = null, // 물품 이름
    var imageUri : String? = null, //이미지 Uri
    var date : Long? = null, //등록 날짜
    var itemAccount: Int? = null, //물품 가격
    var item_text: String? = null, //물품에 대한 내용
    var likeCount: Int = 0
){
    data class Comment(
        val uid: String? = null,
        val comment: String? = null,
        val timestamp: Timestamp? = null,
        val likeCount: Int? = null
    )
}

카드뷰 세팅을 위해 card_layout.xml을 작성

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp"
    card_view:cardBackgroundColor="#f7f2f3"
    card_view:cardCornerRadius="20dp"
    card_view:cardElevation="3dp"
    card_view:contentPadding="4dp">

    <RelativeLayout
        android:layout_width="400dp"
        android:layout_height="150dp"
        android:clickable="true"
        android:padding="16dp">

        <ImageView
            android:id="@+id/item_image"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_alignParentStart="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            card_view:srcCompat="@drawable/ic_launcher_foreground" />


        <TextView
            android:id="@+id/item_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_toEndOf="@+id/item_image"
            android:layout_toRightOf="@id/item_image"
            android:text="TextView 입니다"
            android:textColor="#000000"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/item_detail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/item_title"
            android:layout_toEndOf="@+id/item_image"
            android:layout_toRightOf="@+id/item_image"
            android:text="Detail 입니다."
            android:textColor="#000000" />

    </RelativeLayout>

</androidx.cardview.widget.CardView>

그러면 이렇게 카드뷰가 하나 생성됩니다.

이것을 RecyclerView와 엮어서 우선은 5페이지만 구성해서 시간에 따라 화면이 자동으로 넘어가는 걸 구현해보려고 했습니다

다음으로 카드뷰와 출력될 화면을 이어줄 ImageAdapter를 작성했습니다.

class ImageAdapter(
	//각 아이템에 따른 리스트 생성을 위한 가변현 list - MutableList
    private val sliderItems: MutableList<Int>,
    private val viewPager2: ViewPager2
) :

    RecyclerView.Adapter<ImageAdapter.MyViewHolder>(){
    inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        private var itemimage: ImageView = itemView.findViewById<ImageView>(R.id.slide_image)

        fun onBind(image: Int){
        	//imageview에 목록에 해당되는 이미지를 출력
            itemimage.setImageResource(image)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageAdapter.MyViewHolder{
        val cardView = LayoutInflater.from(parent.context).inflate(R.layout.card_image_layout, parent, false)

        return MyViewHolder(cardView)
    }

    override fun onBindViewHolder(holder: ImageAdapter.MyViewHolder, position: Int) {
        holder.onBind(sliderItems[position])

        if(position == sliderItems.size-1){
            viewPager2.post(runnable)
        }
    }

    override fun getItemCount(): Int {
        return 5
    }

	//리스트에 있는 아이템을 전부 복사
    private val runnable = Runnable { sliderItems.addAll(sliderItems)}
}

위의 코드에서 as는 자료형 변환검사를 위해 필요. holder를 RecyclerView.ViewHolder로 다운 캐스팅

인스턴스 = super 클래스로 만든 인스턴스 as 다운 캐스팅할 sub 클래스 타입

Glide는 안드로이드에서 이미를 빠르고 효율적으로 불러올 수 있게 도와주는 라이브러리

  • 뷰에 이미지를 넣으려면 with(), load(), into()로 표현 가능.
/* Activity에서 사용할 경우 */
Glide.with(this)
	.load(R.drawable.img_file_name)
    .into(imageView)
/* ViewHolder에서 사용할 경우 */
Glide.with(itemView)
	.load(R.drawable.img_file_name)
    .into(itemView.imageView)
  • with() : View, Fragment 혹은 Activity로부터 Context를 가져온다.
  • load() : 이미지를 로드한다. 다양한 방법으로 이미지를 불러올 수 있다(Bitmap, Drawable, String, Uri, File, ResourId(Int), ByteArray)
  • into() : 이미지를 보여줄 View를 지정한다.
  • placeholder() : Glide로 이미지 로딩을 시작하기 전에 보여줄 이미지 설정.
  • error(): 리소스를 불러오다가 에러를 발생했을 때 보여줄 이미지 설정.
  • fallback(): load할 url이 null인 경우 등 비어있을 때 보여줄 이미지를 설정.
  • skipMemoryCache(): 메모리에 캐싱하지 않으려면 true
  • diskCacheStrategy(): 디스크에 캐싱하지 않으려면 DiskCacheStrategy.NONE으로 준다. 다음과 같은 옵션이 있다(ALL, AUTOMATIC, DATA, NONE, RESOURCE)

저는 프래그먼트 위에 viewPager2를 세팅했습니다

<androidx.viewpager2.widget.ViewPager2
                android:id="@+id/viewPager_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/linearLayout"
                app:layout_constraintVertical_bias="0.096"
                app:layout_constraintDimensionRatio="1:0.6"
                tools:layout_editor_absoluteX="-16dp" />

저는 viewPager를 가로로 스크롤링 되도록 할 예정.여기에 페이지 표시도 넣었습니다.

binding.viewPager1.orietation = ViewPager2.ORIENTATION_HORIZONTAL

binding.textCurrentBanner.text = getString(R.string.viewpager2_banner, 1, 5)

//string.xml
<string name="viewpager2_banner">%1$d / %2$d </string>

그 다음 viewPager2에 어떻게 출력할 것인지 코드를 작성합니다

binding.viewPager1.apply {
            adapter = ImageAdapter(imageList, binding.viewPager1)
			//페이지당 보이는 인디케이터 움직임은 viewpager를 따라간다           
           	binding.dotsIndicator.attachTo(binding.viewPager1)
            offscreenPageLimit = 1

            registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback(){
                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                    sliderImageHandler.removeCallbacks(sliderImageRunnable)
                    binding.textCurrentBanner.text = getString(R.string.viewpager2_banner, position+1, 5)
                   
					//자동 스크롤은 5초 당 한 번 넘어가도록
					sliderImageHandler.postDelayed(sliderImageRunnable, 5000)
                }
            })
            setPageTransformer{ page, position ->
            }
        }
  • registerOnPagerChangeCallback - viewpager1의 addPageChangeListener를 대체

이 부분에서 화면이 넘어갈 때 액션을 처리.

registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback(){
                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                    sliderImageHandler.removeCallbacks(sliderImageRunnable)
                    binding.textCurrentBanner.text = getString(R.string.viewpager2_banner, position+1, 5)
                   
					//자동 스크롤은 5초 당 한 번 넘어가도록
					sliderImageHandler.postDelayed(sliderImageRunnable, 5000)
                }
            })
profile
뉴비 프로그래머

0개의 댓글