본문 바로가기

Android/참고

[Kotlin] Recyclerview

0. 그래들 추가

implementation 'com.android.support:recyclerview-v7:27.1.1'


1-1. 아이템 레이아웃 정의

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">

<ImageView
android:id="@+id/sticker"
android:src="@drawable/ic_open_book"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="10dp"/>

<TextView
android:id="@+id/category"
android:text="@string/text_sample"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:padding="5dp"/>
</LinearLayout>


1-2. 아이템 정의

data class DailyItem(val sticker: Int, val category: String)


2. 어댑터(Recyclerview.Adapter<정의한 뷰홀더> 상속해야함) 및 뷰홀더 정의

class DailyListItemRecyclerviewAdapter(private val items: ArrayList<DailyItem>, private val context: Context) : RecyclerView.Adapter<DailyListItemRecyclerviewAdapter.ViewHolder>(){

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

override fun getItemCount(): Int = items.size

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.setItem(items[position])
}

fun addItem(item: DailyItem){
items.add(item)
}

inner class ViewHolder(private val mView: View) : RecyclerView.ViewHolder(mView){
private val mSticker: ImageView = mView.findViewById(R.id.sticker)
private val mCategory: TextView = mView.findViewById(R.id.category)

fun setItem(item: DailyItem){
mSticker.setImageResource(item.sticker)
mCategory.text = item.category
}
}
}

저 context 받아오는것 때문에 되게 오래걸림. ㅡㅡ;;


3. 리사이클러뷰 뿌리기

val recyclerview: RecyclerView = view.findViewById(R.id.daily_list)
recyclerview.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)

val list = ArrayList<DailyItem>()

list.add(DailyItem(R.drawable.ic_money, "오늘 하루 쓴 돈"))
list.add(DailyItem(R.drawable.ic_reminder, "기억해야할 것"))
list.add(DailyItem(R.drawable.ic_open_book, "하루 일기장"))

recyclerview.adapter = DailyListItemRecyclerviewAdapter(list, context!!)


확실히 안드로이드보다 코드가 간결한데, 아직 너무너무너무 어색하다.

그래서 잊지 않기 위해 정리!!!


# 다시한번 내용 정리

- 리사이클러뷰에 보여질 아이템들의 각 요소들(예를 들면 타이틀, 이미지, 내용 등)은 객체(위에서는 DailyItem)로 정의하여 객체단위로 다룰 것.

data class DailyItem(val sticker: Int, val category: String)
val list = ArrayList<DailyItem>()

list.add(DailyItem(R.drawable.ic_money, "오늘 하루 쓴 돈"))
list.add(DailyItem(R.drawable.ic_reminder, "기억해야할 것"))
list.add(DailyItem(R.drawable.ic_open_book, "하루 일기장"))


- 뷰홀더의 역할

 1. 레이아웃 xml로 정의한 뷰들을 inflate(메모리에 올리는 과정 ex. 메인액티비티 onCreate()안에 setContentView작업과 동일)

 2. 아이템.타이틀 (자바는 get메소드로 가져왔지만 코틀린은 그냥 참조) 식으로 해서 뷰에 set (이것을 바인드라고 하는것같음)

inner class ViewHolder(private val mView: View) : RecyclerView.ViewHolder(mView){
private val mSticker: ImageView = mView.findViewById(R.id.sticker)
private val mCategory: TextView = mView.findViewById(R.id.category)

fun setItem(item: DailyItem){
mSticker.setImageResource(item.sticker)
mCategory.text = item.category
}
}


- 어댑터의 역할

 1. 리사이클러뷰에 보여질 아이템들 저장 및 관리

val list = ArrayList<DailyItem>()
list.add(DailyItem(R.drawable.ic_money, "오늘 하루 쓴 돈"))
list.add(DailyItem(R.drawable.ic_reminder, "기억해야할 것"))
list.add(DailyItem(R.drawable.ic_open_book, "하루 일기장"))

recyclerview.adapter = DailyListItemRecyclerviewAdapter(list, context!!)


 2. Recyclerview.Adapter<정의한 뷰홀더>를 상속받아 뷰홀더를 생성해주고 바인딩

class DailyListItemRecyclerviewAdapter(private val items: ArrayList<DailyItem>, private val context: Context) : RecyclerView.Adapter<DailyListItemRecyclerviewAdapter.ViewHolder>(){

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

override fun getItemCount(): Int = items.size

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.setItem(items[position])
}

- 이벤트 처리는 아직 안했음



# 추가적으로 기억할 것

- nullable과 아닌것은 타입이 다르기때문에 대입 불가. 따라서 !! 붙여주면 해결(강제캐스팅)

ex) val builder: AlertDialog.Builder = AlertDialog.Builder(context!!)

- 부모 액티비티 context의 layoutInflater 가져오는 방법

 + 나는 그냥 layoutInflater 라고 가져왔다가 알수없는 오류(무한 루프같은)가 발생하고 결국 꺼졌다.

val view = LayoutInflater.from(context).inflate(R.layout.fragment_day_list, null)



이벤트 처리는 다음에 수정할 것

오늘은 너무 많이했음


'Android > 참고' 카테고리의 다른 글

[Android] android:src VS app:srcCompat  (0) 2018.12.26
[kotlin] TextView 에 밑줄긋기  (0) 2018.10.01
[Kotlin] n초 뒤 화면 전환  (0) 2018.07.06
[Kotlin] 인터페이스 구현할때  (0) 2018.07.06
[Android] 툴바 테두리 없애기  (0) 2018.07.05