리사이클러 뷰

k_hyun·2023년 2월 19일
0

리사이클러 뷰

목록 화면을 만들 때 사용한다.

아래와 같은 구성 요소를 이용해야 한다.

  • ViewHolder(필수) - 항목에 필요한 뷰 객체
  • Adapter - 항목을 구성한다. 적절한 데이터를 뷰 객체에 대입
  • LayoutManager(필수) - 항목을 배치한다.
  • ItemDecoration - 항목을 꾸민다.
<!-- 리사이클러 뷰 등록 -->
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
<!-- 목록에 표시할 항목 디자인 -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_root"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="16dp">
    <TextView
        android:id="@+id/item_data"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textSize="16dp"/>
</LinearLayout>

ViewHolder 및 Adapter

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

        val datas= mutableListOf<String>()//리사이클러뷰에 넣을 항목들
        for(i in 1..10){
            datas.add("item ${i}")
        }
		
        // 리사이클러 뷰에 어댑터와 레이아웃 매니저 등록
        binding.recyclerView.layoutManager=LinearLayoutManager(this)
        binding.recyclerView.adapter=MyAdapter(datas)

    }

    class MyViewHolder(val binding:ItemMainBinding): RecyclerView.ViewHolder(binding.root)

    class MyAdapter(val datas:MutableList<String>):
        RecyclerView.Adapter<RecyclerView.ViewHolder>(){

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {//뷰 홀더의 뷰에 데이터 출력
            return MyViewHolder(ItemMainBinding.inflate(LayoutInflater.from(parent.context)))
        }

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {//항목의 뷰를 가지는 뷰 홀더를 준비
            val binding=(holder as MyViewHolder).binding
            binding.itemData.text=datas[position]
            binding.itemRoot.setOnClickListener{
                Log.d("kkang","item root click")
            }
        }

        override fun getItemCount(): Int {//항목의 개수를 판단
            return datas.size
        }
    }

MainActivity.kt에 뷰홀더와 어댑터를 작성하고 onCreate 함수에서 리사이클러뷰에 원하는 뷰를 나타낸다.

레이아웃 매니저

어댑터로 만든 항목을 리사이클러 뷰에 배치한다.

  • LinearLayoutManager: 항목을 가로나 세로 방향으로 배치
  • GridLayoutManger: 항목을 그리드로 배치
  • StaggeredGridLayoutManager: 항목을 높이가 불규칙한 그리드로 배치

아이템 데커레이션

리사이클러 뷰를 꾸밀 때 사용한다.

// ItemDecoration을 상속하여 클래스를 만든다.
class MyDecoration(val context: Context): RecyclerView.ItemDecoration() {
	
    // 항목이 배치되기 전에 호출
	override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        c.drawBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.intro), 0f, 0f, null)
    }
    
	// 모든 항목이 배치된 후 호출
    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDrawOver(c, parent, state)
        val width = parent.width
        val height = parent.height
        val dr: Drawable? = ResourcesCompat.getDrawable(context.getResources(), R.drawable.img, null)
        val drWidth = dr?.intrinsicWidth
        val drHeight = dr?.intrinsicHeight
        val left = width / 2 - drWidth?.div(2) as Int
        val top = height / 2 - drHeight?.div(2) as Int
        c.drawBitmap(
            BitmapFactory.decodeResource(context.getResources(), R.drawable.img),
            left.toFloat(),
            top.toFloat(),
            null
        )
    }
	// 개별 항목을 꾸밀 때 호출
    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        super.getItemOffsets(outRect, view, parent, state)
        val index = parent.getChildAdapterPosition(view) + 1
        if (index %3 == 0)
            outRect.set(10,10,10,60)
        else
            outRect.set(10,10,10,0)
        view.setBackgroundColor(Color.LTGRAY)
        ViewCompat.setElevation(view, 20.0f)
    }
}


위의 사진은 onDraw()때, 아래 사진은 onDrawOver()때 그려진다.

0개의 댓글