20230830 ViewType

기메단·2023년 8월 30일
1

TIL

목록 보기
31/44


하나의 recyclerview에 두 가지 viewtype을 사용해보자.

@data class

data class MyList(
    val aImage:Int,
    val aName:String,
    val aNumber:String,
    var aLike:Boolean = true) {
}
즐겨찾기 여부에 따라서 뷰타입을 나눌 것이다. true로 초기화. 

@MyAdapter.kt

class MyAdapter (val mItems:MutableList<MyList>) :RecyclerView.Adapter<RecyclerView.ViewHolder>() {

	// 코드에서 VIEW_TYPE_NORMAL과 VIEW_TYPE_FAVORITE는 두 가지 다른 뷰 타입을 나타낸다. 
    // 일반 아이템과 즐겨찾기 아이템을 구분하기 위해 사용되며, 
    // 각각의 뷰 타입에 따라 다른 뷰 홀더와 레이아웃이 사용된다.
    companion object {
        const val VIEW_TYPE_NORMAL = 0
        const val VIEW_TYPE_FAVORITE = 1
    } 

	// 뷰 홀더를 생성하는 역할을 한다.
    // viewType 매개변수를 통해 각 아이템의 뷰 타입을 받아서 해당 뷰 홀더를 생성함.
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        when (viewType) {
            VIEW_TYPE_NORMAL -> {
                var binding =
                    ItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
                return oneHolder(binding)
            }

            VIEW_TYPE_FAVORITE -> {
                var binding =
                    Item22Binding.inflate(LayoutInflater.from(parent.context), parent, false)
                return twoHolder(binding)
            }

            else -> throw IllegalArgumentException("공백")
        }
    }

	// viewHoldr에 데이터를 바인딩하여 화면에 표시.
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is oneHolder) {
            holder.bind(mItems[position])
        } else if (holder is twoHolder) {
            holder.bind(mItems[position])
        }
    }
	
    // 각 아이템의 뷰 타입을 반환한다. 
    // 이 함수를 통해 아이템마다 다른 뷰 홀더와 레이아웃을 사용할 수 있다.
    override fun getItemViewType(position: Int): Int {
        val like = mItems[position]
        return if (like.aLike) {
            VIEW_TYPE_FAVORITE
        }  else {
            VIEW_TYPE_NORMAL
        }
    }
    // Like의 Boolean 값에 따라 viewType이 달라짐.

	// 아이템의 식별자를 반환. 
    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

	// 전체 아이템의 개수를 반환
    override fun getItemCount(): Int {
        return mItems.size
    }

	// 내부클래스인 ItemBinding은 
    // RecyclerView.ViewHolder를 상속받은 뷰 홀더 클래스로, 
    // ItemBinding을 사용하여 아이템의 데이터를 뷰에 바인딩한다. (item.xml)
    inner class oneHolder(private val binding: ItemBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind(item: MyList) {
            binding.imageView.setImageResource(item.aImage)
            binding.textView.text = item.aName
            binding.textView2.text = item.aNumber
        }

    }

	// RecyclerView.ViewHolder를 상속받은 뷰 홀더 클래스로,
    // Item2Binding을 사용하여 아이템의 데이터를 뷰에 바인딩한다.
    // item2.xml
    inner class twoHolder(private val binding: Item2Binding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(item: MyList) {
            binding.imageView1.setImageResource(item.aImage)
            binding.textView3.text = item.aName
            binding.textView4.text = item.aNumber
        }
    }
}

@MainActivity.kt

class MainActivity : AppCompatActivity() {

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

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

        val dataList = mutableListOf<MyList>()
        dataList.add(MyList(R.drawable.image, "친구1", "010-0000-0000",true))
        dataList.add(MyList(R.drawable.ex2, "친구2", "010-0000-0001",false))
        dataList.add(MyList(R.drawable.image, "친구3", "010-0000-0002",true))
        dataList.add(MyList(R.drawable.ex2, "친구4", "010-0000-0003", true))
        dataList.add(MyList(R.drawable.image, "친구5", "010-0000-0004", false))
        dataList.add(MyList(R.drawable.ex2, "친구6", "010-0000-0005",false))
        dataList.add(MyList(R.drawable.image,"친구7", "010-0000-0006",false))
        dataList.add(MyList(R.drawable.ex2, "친구8", "010-0000-0007",true))
        dataList.add(MyList(R.drawable.image, "친구9", "010-0000-0008",true))

        binding.recycler.adapter = MyAdapter(dataList)

        val adapter = MyAdapter(dataList)
        binding.recycler.adapter = adapter
        binding.recycler.layoutManager = LinearLayoutManager(this)
		
        // recyclerview의 divider 생성. 
        val dividerItemDecoration = DividerItemDecoration(binding.recycler.context, LinearLayoutManager(this).orientation)
        binding.recycler.addItemDecoration(dividerItemDecoration)
		
        // 아래부터는 divider의 간격을 줄여주기 위한 코드. 
        val spaceDecoration = VerticalSpaceItemDecoration(30)
        binding.recycler.addItemDecoration(spaceDecoration)

    }

    inner class VerticalSpaceItemDecoration(private val verticalSpaceHeight: Int) :
        RecyclerView.ItemDecoration() {

        override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State
        ) {
            outRect.bottom = verticalSpaceHeight
            outRect.top = verticalSpaceHeight
        }
    }
}

2개의 댓글

comment-user-thumbnail
2023년 8월 30일

후발대 과제인가보네요 강쥐 넘 귀여워요!

답글 달기
comment-user-thumbnail
2023년 8월 30일

data class 의 Boolean 값을 초기화 해주셨군요! 만약 초기화 하지않고 타입만 작성하면 true라고 저는 생각했는데 그게 아니더라구요 ㅇㅅㅇ 궁금하시죠?

답글 달기