본문 바로가기
개발

안드로이드 코틀린: recyclerview

by kks950115 2024. 1. 3.
728x90

 

recyclerview를 설명하기 전에 listview와 gridview를 설명하겠다.

이해를 돕기 위한 것도 있고 시기 상으로 이 둘이 먼저 먼저 나왔고 이 둘의 단점을 보완한 것이 recyclerview이다.

 

gridview와 listview는 리스트를 구현할 때 생성과 삭제를 반복하게 된다. 이들 하나하나가 객체라서 객체의 생성과 삭제를 반복하는 것은 성능 상 좋지 않기 때문에 recyclerview가 나왔다.

 

recyclerview 를 한글로 번역하면 재활용뷰라고 할 수 있다. 말 그대로 생성과 삭제를 하지 않고 썼던 것을 변경해서 다시 쓰는 것이다.

 

그림을 보면 이해가 빠를 것이다.

 

 

 

 

 

왼쪽이 gridview와 listview . 오른쪽이  recyclerview 의 작동흐름이다. 

 

recyclerview 를 사용하기 위해서는 adapter 와 viewholder를 알고 있어야 한다.

 

adapter는 데이터를 recyclerview가 필요로 하는  요구사항에 맞춰서 전해주기 위한 객체이다.

콘센트를 생각하면 편할 것이다. 우리나라는 220v를 쓰지만 220v를 쓰지 않는 나라에서는 변환플러그를 사용해야 한다. adapter는 변환 플러그 같은 것이다.

 

viewholder는 빈 그릇이라고 생각하면 된다.

listview와 gridview는 사용하고 난 다음 그릇을 버리지만 recyclerview는 버리지 않고 재사용한다.

 

예제코드

MainActivity.kt

package com.example.testuse


import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.testuse.databinding.ActivityMainBinding
import com.example.testuse.databinding.ItemRecyclerviewBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding:ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        binding = ActivityMainBinding.inflate(layoutInflater)
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        // 데이터 원본 준비
        val dataList = mutableListOf<MyItem>()
        dataList.add(MyItem(R.drawable.a_123, "Bella", "1"))
        dataList.add(MyItem(R.drawable.a_123, "Charlie", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Daisy", "1.5"))
        dataList.add(MyItem(R.drawable.a_123, "Duke", "1"))
        dataList.add(MyItem(R.drawable.a_123, "Max", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Happy", "4"))
        dataList.add(MyItem(R.drawable.a_123, "Luna", "3"))
        dataList.add(MyItem(R.drawable.a_123, "Bob", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Charlie", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Daisy", "1.5"))
        dataList.add(MyItem(R.drawable.a_123, "Duke", "1"))
        dataList.add(MyItem(R.drawable.a_123, "Max", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Happy", "4"))
        dataList.add(MyItem(R.drawable.a_123, "Luna", "3"))
        dataList.add(MyItem(R.drawable.a_123, "Bob", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Charlie", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Daisy", "1.5"))
        dataList.add(MyItem(R.drawable.a_123, "Duke", "1"))
        dataList.add(MyItem(R.drawable.a_123, "Max", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Happy", "4"))
        dataList.add(MyItem(R.drawable.a_123, "Luna", "3"))
        dataList.add(MyItem(R.drawable.a_123, "Bob", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Charlie", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Daisy", "1.5"))
        dataList.add(MyItem(R.drawable.a_123, "Duke", "1"))
        dataList.add(MyItem(R.drawable.a_123, "Max", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Happy", "4"))
        dataList.add(MyItem(R.drawable.a_123, "Luna", "3"))
        dataList.add(MyItem(R.drawable.a_123, "Bob", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Charlie", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Daisy", "1.5"))
        dataList.add(MyItem(R.drawable.a_123, "Duke", "1"))
        dataList.add(MyItem(R.drawable.a_123, "Max", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Happy", "4"))
        dataList.add(MyItem(R.drawable.a_123, "Luna", "3"))
        dataList.add(MyItem(R.drawable.a_123, "Bob", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Charlie", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Daisy", "1.5"))
        dataList.add(MyItem(R.drawable.a_123, "Duke", "1"))
        dataList.add(MyItem(R.drawable.a_123, "Max", "2"))
        dataList.add(MyItem(R.drawable.a_123, "Happy", "4"))
        dataList.add(MyItem(R.drawable.a_123, "Luna", "3"))
        dataList.add(MyItem(R.drawable.a_123, "Bob", "2"))

        binding.recyclerv.adapter = MyAdapter(dataList)

        val adapter = MyAdapter(dataList)
        binding.recyclerv.adapter = adapter
        binding.recyclerv.layoutManager = LinearLayoutManager(this)

        adapter.itemClick = object : MyAdapter.ItemClick {
            override fun onClick(view: View, position: Int) { // 이 예제는 구현을 main에서 했다.
                val name: String = dataList[position].aName
                Toast.makeText(this@MainActivity," $name 선택!", Toast.LENGTH_SHORT).show()
            }
        }

    }
}

data class MyItem(val aIcon:Int,val aName:String,val aAge:String)


class MyAdapter(val mItems: MutableList<MyItem>) : RecyclerView.Adapter<MyAdapter.Holder>() {

    interface ItemClick {
        fun onClick(view : View, position : Int)
    }

    var itemClick : ItemClick? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
        val binding = ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return Holder(binding)
    }

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.itemView.setOnClickListener {  //클릭이벤트추가부분
            itemClick?.onClick(it, position)
        }
        holder.iconImageView.setImageResource(mItems[position].aIcon)
        holder.name.text = mItems[position].aName
        holder.age.text = mItems[position].aAge
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

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

    inner class Holder(val binding: ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root) {
        val iconImageView = binding.icon
        val name = binding.name
        val age = binding.age
    }
}

 

activity_main.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"
    tools:context=".MainActivity">


    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

item_recyclerview.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="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <ImageView
            android:id="@+id/icon"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:layout_gravity="center_vertical"
            android:padding="8dp"
            android:scaleType="centerCrop"
            android:src="@drawable/a_123"/>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:orientation="vertical">
            <TextView
                android:id="@+id/name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/black"
                android:textSize="20sp"
                android:padding="4dp"
                android:hint="name"/>
            <TextView
                android:id="@+id/age"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/black"
                android:textSize="20sp"
                android:padding="4dp"
                android:hint="age"/>
        </LinearLayout>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

728x90
반응형

댓글