새 시리즈 포스팅입니다.
기본 에제 - 좌/우 스와이프로 삭제/통화 걸기 구현 - 검색 구현 - AAC MVVM적용
이렇게 총 네편으로 포스팅 할 예정입니다.
RecyclerView란?
ViewHolder 패턴을 사용해 아이템 뷰를 재활용하는 리스트입니다.
리스트의 아이템이 1억개가 있다고 해도, 아이템 뷰를 일정 갯수로 유지하며 값만 바꿔 보여주는 것이지요.
사용자의 입장에선 1억개가 다 세팅되어 있는것 같지만, 사실 사용하는 아이템뷰는 극히 적고, 값만 바뀌어서 재배치 되는거죠.
이를 통해 리스트의 규모가 클수록 사용자의 사용환경을 쾌적하게 만들어 주는데 굉장한 효과를 발휘합니다.
추가적으로, RecyclerView는 좌우 스와이프 및 검색을 위한 필터 등의 추가기능을 부착하기 굉장히 쉽습니다.
재료들
1. 아이템들을 출력할 RecyclerView
2. 아이템을 표현할 view
3. 아이템의 값(DTO)
3. 아이템들을 유지/관리하는 Adapter
4. RecyclerView를 출력할 방법을 결정할 layout manager
재료들 구현하기
1. 아이템을 출력할 RecyclerView를 mxl에 추가
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_phone_book"
android:layout_width="match_parent"
android:layout_height="match_parent" />
리스트를 위치할 곳에 RecyclerView를 선언합니다.
2. 아이템의 view
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#ffffff"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_person_phone_book_list_item"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:src="@drawable/ic_person"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_weight="1"
android:id="@+id/tv_name_phone_book_list_item"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center|left"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="이름"
android:textColor="@color/black"
android:textSize="20dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_phone_number_phone_book_list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|left"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="전화번호"/>
</LinearLayout>
</LinearLayout>
3. 아이템들의 값(DTO)
data class PersonDTO(
var no: Int,
var name: String,
var phoneNumber: String,
var imagePath: String = "none",
){}
3-1. 아이템들을 유지/관리하는 adapter
class PhoneBookListAdapter(var persons: Array<Person>, var con: Context) :
RecyclerView.Adapter<PhoneBookListAdapter.ViewHolder>() {
var TAG = "PhoneBookListAdapter"
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
lateinit var iv_person_phone_book_list_item: ImageView
lateinit var tv_name_phone_book_list_item: TextView
lateinit var tv_phone_number_phone_book_list_item: TextView
init {
iv_person_phone_book_list_item = itemView.findViewById(R.id.iv_person_phone_book_list_item)
tv_name_phone_book_list_item = itemView.findViewById(R.id.tv_name_phone_book_list_item)
tv_phone_number_phone_book_list_item = itemView.findViewById(R.id.tv_phone_number_phone_book_list_item)
itemView.setOnClickListener {
AlertDialog.Builder(con).apply {
var position = adapterPosition
var person = persons[position]
setTitle(person.name)
setMessage(person.phoneNumber)
setPositiveButton("OK", DialogInterface.OnClickListener { dialog, which ->
Toast.makeText(con, "OK Button Click", Toast.LENGTH_SHORT).show()
})
show()
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val con = parent.context
val inflater = con.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.item_phonebook, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val person: Person = persons[position]
//[수정요함] 이미지 작업의 경우 glide를 사용해 server의 image를 불러올 것
//holder.iv_person_phone_book_list_item
holder.tv_name_phone_book_list_item.text = person.name
holder.tv_phone_number_phone_book_list_item.text = person.phoneNumber
}
override fun getItemCount(): Int {
return persons.size
}
}
여기서, 계속해서 값만 바뀌며 재활용되는 view는 ViewHolder입니다.
Adapter는 위치에 알맞은 값을 ViewHolder에 세팅하고, 반환해 목록에 보여줍니다.
그렇다면, 리스트의 아이템에 클릭 이벤트를 준다면 어디에 줘야 할까요?
바로 ViewHolder입니다. 위의 클릭이벤트는 아이템을 클릭시 alert dialog를 출력하는 코드입니다.
4. Adapter와 RecyclerView 결합 및 배열 아이템 주입
fun tempPersons(): Array<Person> {
return arrayOf(
Person(1, "kim", "01011111111"),
Person(2, "lee", "01022222222"),
Person(3, "park", "01033333333"),
Person(4, "son", "01044444444"),
Person(5, "hwang", "01055555555"),
Person(6, "jo", "01066666666"),
Person(7, "gwak", "01077777777"),
Person(8, "sim", "01088888888"),
Person(9, "choi", "01099999999"),
)
}
fun setAdapter(){
//리사이클러뷰에 리사이클러뷰 어댑터 부착
rv_phone_book.layoutManager = LinearLayoutManager(this)
phoneBookListAdapter = PhoneBookListAdapter(persons, this)
rv_phone_book.adapter = phoneBookListAdapter
}
위에 세팅해둔 아이템들을 주입하면 되겠습니다.
+ MainActivity 전체 코드
class MainActivity : AppCompatActivity() {
lateinit var rv_phone_book: RecyclerView
lateinit var phoneBookListAdapter: PhoneBookListAdapter
lateinit var persons:Array<Person>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rv_phone_book = findViewById(R.id.rv_phone_book)
persons = tempPersons()
setAdapter()
}
fun setAdapter(){
//리사이클러뷰에 리사이클러뷰 어댑터 부착
rv_phone_book.layoutManager = LinearLayoutManager(this)
phoneBookListAdapter = PhoneBookListAdapter(persons, this)
rv_phone_book.adapter = phoneBookListAdapter
}
fun tempPersons(): Array<Person> {
return arrayOf(
Person(1, "kim", "01011111111"),
Person(2, "lee", "01022222222"),
Person(3, "park", "01033333333"),
Person(4, "son", "01044444444"),
Person(5, "hwang", "01055555555"),
Person(6, "jo", "01066666666"),
Person(7, "gwak", "01077777777"),
Person(8, "sim", "01088888888"),
Person(9, "choi", "01099999999"),
)
}
}
결과
예제 코드 전체 보기
https://github.com/gr2nsky/RecyclerViewPractice/tree/Basic
RecyclerView 시리즈 다른글 보러가기
2022.02.05 - [IDE & Framework/Android] - [Kotlin] RecyclerView (2) - Filter와 SerachView로 검색기능 구현
2022.02.08 - [IDE & Framework/Android] - [Kotlin] RecyclerView (3) - ItemTouchHelper로 Swipe event 구현
'IDE & Framework > Android' 카테고리의 다른 글
[Kotlin] RecyclerView (2) - Filter와 SerachView로 검색기능 구현 (2) | 2022.02.05 |
---|---|
[Kotlin] ViewPager2 사용하기 (0) | 2022.01.31 |
Android Background Service 작업 제한 (1) | 2022.01.22 |
[Kotlin]local properties에 변수 저장하기 (3) | 2022.01.22 |
[Kotlin] Broadcast recevier란? 사용법과 예제 (1) | 2022.01.15 |