티스토리 뷰

728x90

 


RecyclerView

• 컨테이너 뷰에 자식 뷰들을 동적으로 넣는 방법.

• 같은 틀(배치, 속성)에 내용물만 다른 형태 뷰들을 반복적으로 넣을 때 사용

 

* addView -> ListView -> RecyclerView 순으로 편하고 성능이 좋다.

• addView

     - 아이템 뷰의 재사용 없이 늘 모든 아이템 뷰를 만든다. -> 성능 저하

     - 데이터의 변화에 대한 갱신이 힘들다.

     - [📱Android/💡개념] 16. AddView

 

[Android/개념] 16. AddView

AddView • 컨테이너 뷰에 자식 뷰들을 동적으로 넣는 방법. • 같은 틀(배치, 속성)에 내용물만 다른 형태 뷰들을 반복적으로 넣을 때 사용 ex) 리스트 • item_add_view16.xml - 아이템으로 쓸 뷰를 생성

apro-developer.tistory.com

• listView

     - 선택적으로 아이템 뷰를 재사용할 수 도, 안 할 수도 있다.

     - 데이터의 변화에 대한 갱신 기능이 있다.

     - 여전히 성능 이슈가 있다.

     - [📱Android/💡개념] 17. ListView

 

[Android/개념] 17. ListView

ListView • 컨테이너 뷰에 자식 뷰들을 동적으로 넣는 방법. • 같은 틀(배치, 속성)에 내용물만 다른 형태 뷰들을 반복적으로 넣을 때 사용 • Adapter를 사용한다. • addView의 단점을 보완한 뷰 - add

apro-developer.tistory.com

• RecyclerView

     - 아이템 뷰를 재사용할 수 있다.

     - 데이터 변화에 대한 갱신 기능이 있다. -> Adapter.notifyDataSetChanged()

     - 성능적으로 뛰어나다. (리소스를 적게 먹는다, 속도가 빠르다.)

     - 유연하다.

     - 세로, 가로, 그리드, 스태거드 그리드 등 배치 방법이 다양하다. -> RecyclerView.layoutManager

 

• activity_recycler_view19.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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"
    android:orientation="vertical"
    tools:context=".RecyclerView_19">

    <TextView
        android:id="@+id/addPeople"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#AAFFAA"
        android:gravity="center"
        android:text="사람 추가"
        android:textSize="40dp" />
    
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.appcompat.widget.LinearLayoutCompat>

 

• RecyclerView_19.kt

package com.example.fastcampus

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class RecyclerView_19 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_recycler_view19)

        // 데이터 준비
        val peopleList = mutableListOf<People>()
        for (i in 0..100) {
            peopleList.add(People("홍길동" + i, i))
        }

        // 어댑터 장착
        val adapter = RecyclerViewAdapter(peopleList, LayoutInflater.from(this), this)
        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
        recyclerView.adapter = adapter

        // 뷰 배치 설정
        recyclerView.layoutManager = LinearLayoutManager(this) // 아무 배치 설정없이 생략 시 기본값 세로
//        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) // 세로
//        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true) // 세로 - 거꾸로
//        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) - 가로
//        recyclerView.layoutManager = GridLayoutManager(this, 2) - 2줄 그리드

        // 데이터 변경 갱신
        findViewById<TextView>(R.id.addPeople).setOnClickListener {
            adapter.peopleList.add(People("새로운 홍길동", 1234)) // 데이터 추가(변경)
            adapter.notifyDataSetChanged() // 데이터 갱신
        }
    }
}

// 어댑터 정의
class RecyclerViewAdapter( // Outer Class (외부 클래스)
    var peopleList: MutableList<People>,
    var inflater: LayoutInflater,
    var context: Context
): RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() { // 내부에서 정의한 뷰 홀더의 자료형
    inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
        // Inner Class (내부 클래스)
        val peopleImage: ImageView
        val peopleName: TextView
        val peopleAge: TextView

        init {
            peopleImage = itemView.findViewById(R.id.peopleImage)
            peopleName = itemView.findViewById(R.id.peopleName)
            peopleAge = itemView.findViewById(R.id.peopleAge)
            itemView.setOnClickListener { // 아이템 뷰마다 리스너 장착
                val position: Int = adapterPosition // 몇 번째 아이템 뷰인지 가져오기
                val people = peopleList[position]
                Toast.makeText(context, "이름 : " + people.name + " / 나이 : " + people.age, Toast.LENGTH_LONG).show()
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        // xml로 작성한 아이템 뷰를 inflater를 통해 객체로 만든 후 리턴
        val view = inflater.inflate(R.layout.item_add_view16, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // 아이템 뷰와 데이터를 바인딩한다.
        holder.peopleImage.setImageDrawable(context.resources.getDrawable(R.drawable.people4, null))
        holder.peopleName.text = peopleList[position].name
        holder.peopleAge.text = peopleList[position].age.toString()
    }

    override fun getItemCount(): Int {
        // 전체 데이터 크기(개수)
        return peopleList.size
    }
}

 

• 결과

홍길동0 ~ 홍길동100 모두 출력 - 101개가 모두 만들어진 것은 아니고 화면 밖으로 사라지는 뷰들을 재사용하여 다시 출력하는 것이다.

 

사람 추가를 누르면 peopleList에 새로운 항목이 추가되고(데이터의 변경) Adapter.notifyDataSetChanged()를 통해 갱신된다.

 

adapterPosition를 통해 몇 번째 아이템 뷰가 눌렸는지 확인할 수 있다.

 

 

 

 

 

 

 

 

 

이 글은

패스트 캠퍼스 Android 앱 개발의 정석 with Kotlin 올인원 패키지 Online

강의를 듣고 공부한 내용을 바탕으로 작성되었습니다.

 


728x90
댓글
공지사항