티스토리 뷰
리사이클러뷰(RecyclerView)는 리스트뷰의 개선판으로 뷰 홀더를 포함하고 있습니다. 리사이클러뷰는 리스트를 보여주기에, 기본적으로 ScrollView도 제공합니다.
리사이클러뷰가 많이 사용되는 이유는 LayoutManager의 기능때문입니다. 개발자는 레이아웃 매니저로 인해 레이아웃을 좀 더 유연하게 표현할 수 있습니다.
LayoutManager는 다음의 레이아웃을 지원하고 있습니다.
1. Vertical
2. Horizontal
3. Grid
4. StaggeredGrid
5. Mixed
지원 가능한 레이아웃으로 원하는 뷰를 자유롭게 표현할 수 있어서, 애드뷰, 리스트뷰 보다 더 자주 사용되는 것으로 알고 있습니다.
우선 리사이클러뷰를 사용하기 위해선, Gradle Scripts - build.gradle(Module app) 부분의 의존성 쪽에서 리사이클러뷰사용을 선언해줘야 합니다. 그레이들 스크립트의 모듈/앱 단위 build.gradle의 dependencies 부분에서 recyclerview를 implementation 해주면 됩니다. 그럼 사용할 준비가 완료됩니다!
dependencies {
implementation "androidx.recyclerview:recyclerview:1.1.0"
}
이후로 액티비티 파일에서 adapter 클래스를 생성하도록 합니다.
아래 RecyclerViewAdapter 클래스를 보면, 제너릭 타입의 ArrayList 형의 itemList와 뷰를 뿌려주는 inflater를 인자로 받게 됩니다. 해당 클래스는 RecyclerView.Adapter< >( )를 상속받게 됩니다.
이때, RecyclerView.Adapter< >( )의 꺽쇠 부분에는 제너릭 타입으로 해당 클래스의 뷰 홀더가 와야 합니다. 클래스 안에 아직 뷰 홀더가 없기 때문에, ViewHolder 클래스를 만들어 줍니다.
ViewHolder 클래스는 view 타입의 itemView를 받으며, 이 클래스는 RecyclerView.ViewHolder( ) 타입을 상속 받는데, ViewHolder(itemView)와 같이, 생성자에서 받은 itemView를 부모에게 넘겨주게 됩니다.
뷰 홀더 클래스는 초기화 함수(init)도 지니고 있습니다. init이 실행되면 animalName, animalTyp 변수를 만들어 냅니다.
뷰 홀더를 만들어 줬으니, RecyclerView.Adapter< >( )의 꺽쇠 부분에 제너릭 타입을 적어줍니다. RecyclerView.Adapter<RecyclerView.ViewHolde>( ), 이렇게 말이죠.
그리고 상속받은 Adapter를 implement 시켜줍니다. 그럼, onCreateViewHolder, getItemCount, onBindViewHolder 메소드가 들어오게 됩니다. onCreateViewHolder는 뷰를 만들어주는 곳이며, getItemCount는 리스트뷰의 크기를 리런해주는 부분, onBindViewHolder는 리스트뷰에서 태그를 달아 태그를 가져오는 역할을 하는 부분과 비슷하며, 뷰를 그려주는 곳입니다.
class RecyclerViewAdapter(
var itemList: ArrayList<AnimalList>,
val inflater: LayoutInflater
) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val animalName: TextView
val animalType: TextView
init {
animalName = itemView.findViewById(R.id.animal_name)
animalType = itemView.findViewById(R.id.animal_type)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
}
override fun getItemCount(): Int {
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
}
}
implement된 메소드 부분을 완성하면, 아래 코드와 같습니다.
onCreateViewHolder 부분을 보면, view에 인플레이터를 사용해서 원하는 뷰를 부착해줘야 합니다. R.layout.item_view로 원하는 뷰를 가져오고, 컨테이너 부분은 parent로 지정합니다. 세 번째 부분인 attachToRoot 부분인데, false 해줍니다. true 값은 자식 뷰를 parent에 바로 부착하는 것이고, false는 지금 바로는 부착하지 않습니다. 리턴 값으로 view를 받은 뷰 홀더를 리턴하게 됩니다.
getItemCount는 말그대로 보여줄 리스트뷰의 크기를 리턴해주는 곳입니다.
onBindViewHolder는 뷰홀더 클래스에서 init으로 생성된 animalName, animalType을 holder.animalName.setText로 받아와 실제 뷰를 넣어줍니다.
전체적인 흐름은 다음과 같습니다.
1. 아이템 하나가 들어갈 뷰를 뷰 홀더에 넣어서 onCreateViewHolder의 리턴값으로 리턴합니다.
2. 리턴된 뷰는 결국 뷰 홀더 클래스의 itemView로 들어가게 됩니다.
3. 뷰 홀더 클래스에서 itemView가 들어오면, init 값이 생성되며 animalName, animalType을 만들게 됩니다.
4. onBindViewHolder에서 이미 만들어 준비된 animalName, animalType에서 setText를 통해 실제 뷰를 전달합니다.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = inflater.inflate(R.layout.item_view, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return itemList.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.animalName.setText(itemList.get(position).name)
holder.animalType.setText(itemList.get(position).type)
}
어댑터를 만들었으니, recycler_view.xml 레이아웃에 장착을 해주도록 합니다. 레이아웃의 id값인 recycler_view를 확인 후 액티비티 파일의 onCreate로 가져옵니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".RecyclerViewActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
액티비티 파일의 onCreate 부분에 코딩해줍니다. 우선 onCreate 클래스에서 adapter를 사용해야 하므로, 어댑터를 만들어줍니다. RecyclerViewAdapter에 어댑터의 도움을 받으려는 리스트와 LayoutInflater를 인수로 넣어줍니다. context(this)를 통해 @해당 액티비티를 명시합니다. 어댑터가 준비되면, 레이아웃 매니저에 원하는 형태의 레이아웃을 사용합니다.
예시 코드에서는 LinearLayoutManager, GridLayoutManager를 이용했습니다.
class RecyclerViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.recycler_view)
val animalList = ArrayList<AnimalList>()
for (i in 0 until 50) {
animalList.add(AnimalList("" + i + " 동물", "" + i + " 동물 유형"))
}
val adapter = RecyclerViewAdapter(animalList, LayoutInflater.from(this@RecyclerView))
recycler_view.adapter = adapter
recycler_view.layoutManager = LinearLayoutManager(this@RecyclerView)
//recycler_view.layoutManager = GridLayoutManager(this@RecyclerView, 2) <- 2줄씩
}
}
아이템을 클릭하면, 원하는 뷰로 넘어가도록 리스너를 달아 봅니다.
애드뷰의 경우에는 뷰를 add( )하기 직전에 리스너를 달았습니다.
리스트뷰의 경우에는 setOnItemClickListener를 통해 원하는 기능을 구현했습니다.
리사이클러뷰의 경우에는 itemView의 위치가 들어오는 뷰 홀더 클래스 안에 setOnClickListener를 달아주는게 좋습니다.
만약 typeName을 토스트 메시지로 보여주는 상황이라면, 포지션을 알아야 합니다. 아이템의 몇 번째를 클릭했는지 그 포지션을 알아야, 해당 번째 AnimalList의 type을 꺼내와 가져올 수 있습니다.
현재 뷰 홀더 클래스의 인자로 position이 들어오지 않기 때문에, adapterPosition 변수를 호출해야 합니다. 해당 변수 호출로 포지션을 전달받을 수 있기 때문입니다.
그리고 itemList로부터 포지션을 통해 type을 가져올 때, itemList는 뷰 홀더 클래스 밖의 RcyclerViewAdapter 클래스에 선언되어 있으므로, ViewHolder 클래스를 inner 클래스로 바꿔야 합니다. inner 키워드를 통해 이너 클래스인 ViewHolder는 외부 클래스인 RecyclerViewAdapter를 접근할 수 있습니다.
class RecyclerViewAdapter(
var itemList: ArrayList<AnimalList>,
val inflater: LayoutInflater
) : RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val animalName: TextView
val animalType: TextView
init {
animalName = itemView.findViewById(R.id.animal_name)
animalType = itemView.findViewById(R.id.animal_type)
itemView.setOnClickListener {
val posintion: Int = adapterPosition
val typeName = itemList.get(posintion).type
토스 메시지 코드 생략
}
}
}
}
'Android App Coding' 카테고리의 다른 글
탭레이아웃 2편 TabLayout (0) | 2021.07.09 |
---|---|
탭레이아웃 TabLayout (0) | 2021.07.09 |
뷰 홀더 View Holder (0) | 2021.07.09 |
토스트 메시지 Toast (0) | 2021.07.09 |
리스트뷰와 어댑터 ListView & Adapter (0) | 2021.07.09 |
- Total
- Today
- Yesterday
- 상대적 레이아웃
- addView
- lazy init
- Bmi Calculator
- 선형 레이아웃
- view binding
- 리스트뷰
- 인텐트
- 뷰 바인딩
- 애드뷰
- 메소드 오버라이딩
- 안드로이드 프로젝트
- tabLayout
- ToDo List 앱 만들기
- 2021년 사건사고
- RecyclerView
- 안드로이드 어댑터
- android adapter
- 탭레이아웃
- 안드로이드 앱 만들기
- 자바스크립트 배열
- bmi 계산기 만들기
- findViewById
- notifyDataSetChanged
- 미제사건
- 리사이클러뷰
- 2019년 사건사고
- 대한민국 미제사건
- 안드로이드 스튜디오 에러
- 2007년 사건사고
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |