일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- FragmentStateAdapter
- Devexpress
- 백준 15686
- 필답고사
- Clean Architecture
- 통계대학원
- Kotiln
- Android 컴파일
- ViewPager2
- 안드로이드 API
- RETROFIT
- Java
- TabLayout
- 안드로이드 플랫폼
- 웹 크롤링
- RecyclerView
- python3
- ViewModel
- kotlin
- Android
- 수리통계
- okHttp
- github api
- AndroidX
- REST API
- gson
- 셀레니움
- 데이터바인딩
- LRU
- TODO
- Today
- Total
그냥 가끔의 기록장
[Kotlin] Todo 토이 프로젝트 [2단계] (ViewPager2 + RecyclerView + ViewModel) 본문
[Kotlin] Todo 토이 프로젝트 [2단계] (ViewPager2 + RecyclerView + ViewModel)
the phoenix 2022. 4. 23. 17:18https://soeun-87.tistory.com/32
앞 글에 이어 2단계로 토이 프로젝트를 마저 구현해 보자.
1. 단계별 코드
(1) RecyclerView Adapter 생성 - DoneFragment, PendingFragment 용
DoneFragment와 Pendingfragment는 각각 RecyclerView를 갖고서 Todo Item들을 보여줘야 하므로, Adapter가 필요하다.
두 가지 Adapter는 지금 당장은 구조가 완전히 동일하므로 (다음 글의 viewModel 도입 시 조금 달라짐, 지금은 같음) TodoPendingAdapter.kt만 설명하고 넘어가겠다.
TodoPendingAdapter는 RecyclerView.Adapter를 상속 받고, TodoPendingAdapter안에 inner class로 TodoViewHolder를 작성해준다. 여기서 ViewHolder는 각 data item을 view를 사용해 화면에 보여주는 역할을 한다.
순서대로 보면
1. TodoViewHolder 작성 및, 내부에 bind() 함수를 작성해 각 Todos list에 있는 data item과 View를 bind해서 title은 tvTitle view에 표시되도록 한다.
2. RecyclerView.Adapter 상속 시 onCreateViewHolder, onBindViewHolder, getItemCount 3가지 함수를 반드시 override 해야 한다. 각 함수가 무슨 역할을 하는지는 주석을 참고하면 된다.
3. 마지막으로 getItemId()라는 함수를 작성해 RecyclerView의 item position에 맞는 id를 반환해준다.
1) TodoPendingAdapter.kt
package com.example.kotlintodo.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.kotlintodo.databinding.ItemTodoBinding
import com.example.kotlintodo.model.Todo
class TodoPendingAdapter(var Todos: List<Todo>): RecyclerView.Adapter<TodoPendingAdapter.ToDoViewHolder>() {
private lateinit var itemBinding: ItemTodoBinding
inner class ToDoViewHolder(private val itemBinding: ItemTodoBinding): RecyclerView.ViewHolder(itemBinding.root){
fun bind(data: Todo) {
itemBinding.tvTitle.text = data.title
itemBinding.tvContent.text = data.content
itemBinding.cbIsDone.isChecked = data.isDone
}
}
// RecyclerView.Adapter 상속 시 무조건 override 해야하는 fun - viewHolder에 layout inflate 하는 함수 (ViewBinding 사용)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ToDoViewHolder {
itemBinding = ItemTodoBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ToDoViewHolder(itemBinding)
}
// RecyclerView.Adapter 상속 시 무조건 override 해야하는 fun - viewHolder에 각 view를 bind하는 함수
// ToDoViewHolder내에 bind함수 정의했으므로, 각 Todos[position]인 item data랑 view를 bind하면 됨
override fun onBindViewHolder(holder: ToDoViewHolder, position: Int) {
holder.bind(Todos[position])
}
// RecyclerView.Adapter 상속 시 무조건 override 해야하는 fun - 보통 Todos.size를 return, RecyclerView내의 item 개수 return하는 함수
override fun getItemCount(): Int {
return Todos.size
}
// Todos list의 각 item id return
override fun getItemId(position: Int): Long {
return position.toLong()
}
}
2) TodoDoneAdapter.kt
package com.example.kotlintodo.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.kotlintodo.databinding.ItemTodoBinding
import com.example.kotlintodo.model.Todo
class TodoDoneAdapter(var Todos: List<Todo>): RecyclerView.Adapter<TodoDoneAdapter.ToDoViewHolder>() {
private lateinit var itemBinding: ItemTodoBinding
inner class ToDoViewHolder(private val itemBinding: ItemTodoBinding): RecyclerView.ViewHolder(itemBinding.root){
fun bind(data:Todo) {
itemBinding.tvTitle.text = data.title
itemBinding.tvContent.text = data.content
itemBinding.cbIsDone.isChecked = data.isDone
}
}
// RecyclerView.Adapter 상속 시 무조건 override 해야하는 fun - viewHolder에 layout inflate 하는 함수 (ViewBinding 사용)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ToDoViewHolder {
itemBinding = ItemTodoBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ToDoViewHolder(itemBinding)
}
// RecyclerView.Adapter 상속 시 무조건 override 해야하는 fun - viewHolder에 각 view를 bind하는 함수
// ToDoViewHolder내에 bind함수 정의했으므로, 각 Todos[position]인 item data랑 view를 bind하면 됨
override fun onBindViewHolder(holder: ToDoViewHolder, position: Int) {
holder.bind(Todos[position])
}
// RecyclerView.Adapter 상속 시 무조건 override 해야하는 fun - 보통 Todos.size를 return, RecyclerView내의 item 개수 return하는 함수
override fun getItemCount(): Int {
return Todos.size
}
// Todos list의 각 item id return
override fun getItemId(position: Int): Long {
return position.toLong()
}
}
(2) DoneFragment, PendingFragment 에 Adapter 연결
RecyclerView Adapter를 생성했으니 RecyclerView를 xml에 포함하고 있는 DoneFragment, PendingFragment에서 adapter를 연동해보자. 두 Fragment의 코드 구조가 동일하므로 PendingFragment만 설명하겠다.
1. view Binding 설정
2. Adapter 설정 (Adapter 인자는 List<Todo> 임에 주의)
=> binding!!.rvPending.adapter = adapter로 연동해준다.
3. RecyclerView에 꼭 Layout 설정해주기
=> 설정 안하면 skip 되어서 에뮬레이터에 아무것도 안뜨게 되므로 꼭 하기!
4. Fragment의 onCreateView는 View를 반환하므로 return binding.root 잊지말기
1) PendingFragment.kt
package com.example.kotlintodo.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.kotlintodo.adapter.TodoPendingAdapter
import com.example.kotlintodo.databinding.FragmentPendingBinding
import com.example.kotlintodo.model.Todo
class PendingFragment: Fragment() {
private lateinit var binding: FragmentPendingBinding
private lateinit var adapter : TodoPendingAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// 1. View Binding 설정
binding = FragmentPendingBinding.inflate(inflater, container, false)
// 2. adapter 설정 (list를 인자로)
adapter = TodoPendingAdapter(listOf(Todo("first title", "first content", false)))
adapter.setHasStableIds(true)
binding!!.rvPending.adapter = adapter
// 3. recyclerView에 Layout 꼭 설정하기 (안그러면 화면에 표시 안되고 skip됨)
binding!!.rvPending.layoutManager = LinearLayoutManager(activity)
// 4. return Fragment Layout View
return binding.root
}
}
2) DoneFragment.kt
package com.example.kotlintodo.ui.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.kotlintodo.adapter.TodoDoneAdapter
import com.example.kotlintodo.databinding.FragmentDoneBinding
import com.example.kotlintodo.model.Todo
class DoneFragment: Fragment() {
private lateinit var binding: FragmentDoneBinding
private lateinit var adapter : TodoDoneAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// 1. View Binding 설정
binding = FragmentDoneBinding.inflate(inflater, container, false)
// 2. adapter 설정 (list를 인자로)
adapter = TodoDoneAdapter(emptyList<Todo>())
adapter.setHasStableIds(true)
binding!!.rvDone.adapter = adapter
// 3. recyclerView에 Layout 꼭 설정하기 (안그러면 화면에 표시 안되고 skip됨)
binding!!.rvDone.layoutManager = LinearLayoutManager(activity)
// 4. return Fragment Layout View
return binding.root
}
}
(3) 여기까지 최종 결과
PendingFragment에 예시로 넣은 item 한개가 보이는 것을 확인할 수 있다.
*GitHub 링크
https://github.com/leesoeun98/KotlinToDo
'Android' 카테고리의 다른 글
[Kotlin] Github API를 이용해 예제 App 만들기 - 1. Retrofit 정복 (0) | 2022.08.01 |
---|---|
[Kotlin] Todo 토이 프로젝트 [3단계] (ViewPager2 + RecyclerView + ViewModel) (1) | 2022.04.30 |
[Kotlin] Todo 토이 프로젝트 [1단계] (ViewPager2 + RecyclerView + ViewModel) (0) | 2022.04.23 |
Android Clean Architecture (0) | 2021.06.08 |
[Kotlin] RecyclerView 예제 (0) | 2021.06.06 |