[개념] 리사이클러뷰에서 ClickListener 추가

쓰리원·2022년 4월 12일
0

RecyclerView

목록 보기
1/1
post-thumbnail

아래는 리사이클러뷰 ClickListener를 공부하기전 사전 지식입니다.

개념-리스트뷰와-리사이클러뷰에서-ViewHolder-패턴-활용

학습을 하기전 필요한 리사이클러뷰 구현 예제코드 링크입니다.
https://github.com/ilil1/RecyclerviewExample

ClickListener를 추가하는 몇가지 방법을 다뤄볼 생각입니다. 이것 말고도 다양한 방법들이 존재할 수 있습니다.

1. 첫번째 방법

1. 변경 전 RecyclerAdapter.kt

class RecyclerAdapter(private val items: ArrayList<Model>) :
    RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val title : TextView = itemView.findViewById(R.id.titleText)
        val content : TextView = itemView.findViewById(R.id.contentText)
        val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)

        fun bind(item: Model) {
            thumbnail.clear()
            title.text = item.title
            content.text = item.content
            thumbnail.load(item.imageurl, 16f)
        }
    }

    override fun getItemCount() = items.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
        val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
        return RecyclerAdapter.ViewHolder(View)
    }

    override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
        val item = items[position]
        holder.bind(item)
    }
}

이전에 작성한 리사이클러뷰 어댑터 코드입니다. 이 코드 내부에 추가되는 코드들이 있습니다 아래에서 소개하겠습니다.

2. 변경 후 RecyclerAdapter.kt

class RecyclerAdapter(private val items: ArrayList<Model>) :
    RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val title : TextView = itemView.findViewById(R.id.titleText)
        val content : TextView = itemView.findViewById(R.id.contentText)
        val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)

        fun bind(item: Model) {
            thumbnail.clear()
            title.text = item.title
            content.text = item.content
            thumbnail.load(item.imageurl, 16f)
        }
    }

    override fun getItemCount() = items.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
        val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
        return RecyclerAdapter.ViewHolder(View)
    }

    // 1. ClickListener 인터페이스
    interface ClickListener {
        fun onClick(v: View, position: Int)
    }
    
    // 2. MainActivity에서 클릭 시 이벤트 설정
    fun setItemClickListener(itemclickListener: ClickListener) {
        this.ItemClickListener = itemclickListener
    }
    
    // 3. setItemClickListener로 받아온 파라미터 할당
    private lateinit var ItemClickListener : ClickListener

    override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
        val item = items[position]
        holder.bind(item)
        // 4. 리스트 내 항목 클릭 시 onClick() 호출
        holder.itemView.setOnClickListener {
            ItemClickListener.onClick(it, position)
        }
    }
}

변경 후 코드입니다 위 코드에 대해서는 MainActivity.kt과 함께 아래에서 설명하겠습니다.

3. 변경 후 MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerview: RecyclerView
    private lateinit var adapter : RecyclerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val list = ArrayList<Model>()
        for(i: Int in 1..10) {
            var contact = Model("Add ", i.toString(), "https://picsum.photos/200")
            list.add(contact)
        }

        recyclerview = findViewById(R.id.recyclerView)

        adapter = RecyclerAdapter(list)
        recyclerview.adapter = adapter
        recyclerview.layoutManager = LinearLayoutManager(this)

        adapter.setItemClickListener(object: RecyclerAdapter.ClickListener {
            override fun onClick(v: View, position: Int) {
                // ClickListener 작성
                Toast.makeText(this@MainActivity,
                    "${list[position].content}",
                    Toast.LENGTH_SHORT).show()
            }
        })
    }
}

MainActivity.kt의 경우 변경전과 변경후에 ClickListner를 추가하는 것말고는 달라지는 것이 없습니다.

추가설명.

// 2. MainActivity에서 클릭 시 이벤트 설정
fun setItemClickListener(itemclickListener: ClickListener) {
	this.ItemClickListener = itemclickListener
}

MainActivity에서 리스너 객체를 받아서 호출이 가능할 수 있도록 하기위해 setItemClickListener를 만들어 줍니다.

setItemClickListener의 경우 ClickListener를 파라미터로 받습니다. 그것을 인터페이스로 만들어 줍니다. 인터페이스로 만들고 MainActivity에서 오버라이드 하여서 Click의 기능을 구현해줍니다.

setItemClickListener(itemclickListener: ClickListener)에서 받아온 파라미터는 private lateinit var ItemClickListener : ClickListener 로 할당됩니다.

// 4. 리스트 내 항목 클릭 시 onClick() 호출
holder.itemView.setOnClickListener {
ItemClickListener.onClick(it, position)
} ItemClickListener는 onClick에 View와 position의 값을 넘겨줘서 이벤트가 최종적으로 발생하게 됩니다.

코드 다운 : https://github.com/ilil1/RecyclerviewClick

2. 두번째 방법

1. 변경 전 RecyclerAdapter.kt

class RecyclerAdapter(private val items: ArrayList<Model>) :
    RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val title : TextView = itemView.findViewById(R.id.titleText)
        val content : TextView = itemView.findViewById(R.id.contentText)
        val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)

        fun bind(item: Model) {
            thumbnail.clear()
            title.text = item.title
            content.text = item.content
            thumbnail.load(item.imageurl, 16f)
        }
    }

    override fun getItemCount() = items.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
        val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
        return RecyclerAdapter.ViewHolder(View)
    }

    override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
        val item = items[position]
        holder.bind(item)
    }
}

이전에 작성한 리사이클러뷰 어댑터 코드입니다. 이 코드 내부에 추가되는 코드들이 있습니다 아래에서 소개하겠습니다.

2. 변경 후 RecyclerAdapter.kt

class RecyclerAdapter(private val items: ArrayList<Model>) :
    RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val title : TextView = itemView.findViewById(R.id.titleText)
        val content : TextView = itemView.findViewById(R.id.contentText)
        val thumbnail : ImageView = itemView.findViewById(R.id.thumbnail)

        fun bind(item: Model) {
            thumbnail.clear()
            title.text = item.title
            content.text = item.content
            thumbnail.load(item.imageurl, 16f)
        }
 		
        fun bindViews(item: Model, listener: ClickListener)  {
            itemView.setOnClickListener {
                listener.onClick(item)
            }
        }
    }

    override fun getItemCount() = items.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerAdapter.ViewHolder {
        val View = LayoutInflater.from(parent.context).inflate(R.layout.board_list, parent, false)
        return RecyclerAdapter.ViewHolder(View)
    }

    // 1. ClickListener 인터페이스
    interface ClickListener {
        fun onClick(item: Model)
    }

    // 2. MainActivity에서 클릭 시 이벤트 설정
    fun setItemClickListener(itemclickListener: ClickListener) {
        this.ItemClickListener = itemclickListener
    }

    // 3. setItemClickListener로 받아온 파라미터 할당
    private lateinit var ItemClickListener : ClickListener

    override fun onBindViewHolder(holder: RecyclerAdapter.ViewHolder, position: Int) {
        val item = items[position]
        holder.bind(item)
        // 4. 리스트 내 항목 클릭 시 onClick() 호출
        holder.bindViews(item, ItemClickListener)
    }
}

3. 변경 후 MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerview: RecyclerView
    private lateinit var adapter : RecyclerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val list = ArrayList<Model>()
        for(i: Int in 1..10) {
            var contact = Model("Add ", i.toString(), "https://picsum.photos/200")
            list.add(contact)
        }

        recyclerview = findViewById(R.id.recyclerView)

        adapter = RecyclerAdapter(list)
        recyclerview.adapter = adapter
        recyclerview.layoutManager = LinearLayoutManager(this)

        adapter.setItemClickListener(object: RecyclerAdapter.ClickListener {
            override fun onClick(item: Model) {
                // 클릭 시 이벤트 작성
                Toast.makeText(this@MainActivity,
                    "${item.content}",
                    Toast.LENGTH_SHORT).show()
            }
        })
    }
}

MainActivity.kt의 경우 이전에는 view와 position을 파라미터로 가졌다면 이번에는 Model을 파라미터로 가지게 됩니다.

profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글