[Kotlin] Viewpager2, Recycler View, Layout Manager
< ViewPager2 >
오랫동안 이용했던 viewpager와 별개로 2019년에 viewpager2를 제공하였다.
항목이 순서대로 나열되어 있는데 한 화면에 항목 하나가 나온다는 개념이다.
어댑터 : 여러 프래그먼트가 포함된 뷰를 제어할 수 있는 것으로 각 항목을 만들어 주는 역할을 한다.
프래그먼트 어댑터 이용 : 프래그먼트로 작성했으면 FragmentStateAdapter로 뷰 페이저 2를 구현 한다.
class MyFragmentPagerAdapter(activity: FragmentActivity): FragmentStateAdapter(activity)
{
val fragments: List<Fragment>
init{
fragments = listOf(OneFragment(), TwoFragment(), ThreeFragment())
Log.d("kkang", "fragments size : ${fragments.size}")
}
override fun getItemCount() : Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}
build.gradle에 dependencies 추가
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation("androidx.viewpager2:viewpager2:1.0.0")
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
프래그먼트를 집어넣는 것은 mainActivity에서 코드를 짠다.
< 리사이클러 뷰 >
리사이클러 뷰 기초 사용법
구성요소
ViewHolder(필수) : 항목에 필요한 뷰 객체를 가집니다, 리사이클러 뷰 한 칸을 의미한다.
Adapter(필수) : 항목을 구성합니다. 각 항목을 만들어 주는 역할을 한다.
LayoutManager(필수) : 항목을 배치합니다.
ItemDecoration(옵션) : 항목을 꾸밉니다.
리사이클러 뷰도 아이템 항목을 다루고 있기 때문에 Adapter가 있어야 합니다.
DB 내용을 리사이클러 뷰항목에 넣을 예정이다.
뷰 홀더 준비
- 각 항목에 해당하는 뷰 객체를 가지는 뷰 홀더는 RecyclerView.ViewHolder를 상속받아 작성
class MyViewHolder(val binding: ItemMainBinding): RecyclerView.ViewHolder(binding.root)
어댑터 준비
- 각 항목을 만들어 주는 역할을 한다
getItemCount() : 항목 개수를 판단하려고 자동으로 호출됩니다.
onCreateViewHolder() : 항목의 뷰를 가지는 뷰 홀더를 준비하려고 자동으로 호출됩니다.
onBindViewHolder() : 뷰 홀더의 뷰에 데이터를 출력하려고 자동으로 호출됩니다.
class MyAdapter(val binding: ItemMainBinding):
RecyclerView.Adapter<RecyclerView.ViewHolder>(){
// 항목의 개수 구하기
override fun getItemCount(): Int = datas.size
// 항목 구성에 필요한 뷰 홀더 객체 준비
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
RecyclerView.ViewHolder = MyViewHolder(ItemMainBinding.inflate(LayoutInflater.from(parent.context),parent, false))
// 뷰에 데이터 출력
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int){
val binding = (holder as MyViewHolder).binding
// 뷰에 데이터 출력
binding.itemData.text = datas[position]
// 뷰에 이벤트 추가
binding.itemRoot.setOnClickListener{
}
}}
RecyclerView.Adapter를 상속받아 getItemCount(), onCreateViewHolder(), onBindViewHolder() 오버라이드 함수를 반드시 포함시켜야 한다. ItemMainBinding XML 파일에서 아이템을 어떻게 배치할 것인지 정하고, ViewHolder 클래스를 정의하여 onCreateViewHolder에서 사용한다.
[필수] Adapter와 ViewHolder 클래스 작성하기
class MyViewHolder(val binding:ItemRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root)
class MyAdapter(val datas:MutableList<String>): RecyclerView.Adapter<RecyclerView.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return MyViewHolder(ItemRecyclerviewBinding.inflate(LayoutInflater.from(parent.context),parent,false))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val binding = (holder as MyViewHolder).binding
binding.itemData.text = datas[position]
}
override fun getItemCount(): Int {
return datas.size
}
}
리사이클러 뷰 출력
class RecyclerViewActivity : AppCompatActivity(){
override fun onCreate(savedInstanceSTate: Bundle?){
super.onCreate(savedInstanceState)
val binding = ActivitiyRecyclerViewBinding.inflate(layoutInflater)
setContentView(binding.root)
val datas = mutableListOf<String>()
for(i in 1..10){
datas.add("item $i")
}
binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = MyAdapter(datas)
binding.recyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayout Manager.VERTICAL))
}
}
항목을 동적으로 추가/제거
항목을 구성하는 데이터에 새로운 데이터를 추가하거나 제거한 후 어댑터의 notifyDataSetChanged() 함수를 호출
datas.add("new data")
adapter.notifyDataSetChanged()
< 레이아웃 매니저로 배치 >
레이아웃 매니저는 어댑터로 만든 항목을 리사이클러 뷰에 배치합니다.
- LinearLayoutManager : 항목을 가로나 세로 방향으로 배치합니다. 디폴트가 vertical이다.
- GridLayoutManager : 항목을 그리드로 배치합니다.
- StaggeredGridLayoutManager : 항목을 높이가 불규칙한 그리드로 배치합니다.
항목을 세로 방향으로 배치
binding.recyclerView.layoutManager =
LinearLayoutManager(this)
항목을 가로 방향으로 배치
val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
binding.recyclerView.layoutManager = layoutManager
< 그리드로 배치 >
GridLayoutManager를 이용하면 한 줄에 두 개 배치도 가능합니다.
생성자의 숫자는 그리드에서 열의 개수를 뜻합니다.
방향을 설정할 수 있습니다.
가로로 설정하려면 생성자에 GridLayoutManager.HORIZONTAL을 지정해야 합니다.
val layoutManager = GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false)
binding.recyclerView.layoutManager = layoutManager
< 아이템 데코레이션 >
아이템 데커레이션은 리사이클러 뷰를 다양하게 꾸밀 때 사용한다. 항목의 구분선을 출력해 주는 DividerItem Decoration이다. ItemDecoration을 상속받는 개발자 클래스를 만들고 이 클래스에서 다양한 꾸미기 작업을 합니다.
onDraw() : 꾸미고 배치, 항목이 배치되기 전에 호출됩니다. 그러고 나서 리사이클러 뷰를 배치합니다.
onDrawOver() : 배치 후 꾸미기, 항목이 모두 배치된 후 호출됩니다. 배치하고 나서 그림을 그립니다.
getItemOffsets() : 각각의 항목을 꾸며준다.
class MyItemDecoration(val context: Context):RecyclerView.ItemDecoration(){
// 꾸미고 배치
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
// 그림 -> 항목
super.onDraw(c, parent, state)
c.drawBitmap(BitmapFactory.decodeResource(context.resources, R.drawable.kbo),
0f, 0f, null)
}
// 배치 후 꾸미기
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
// 항목 -> 그림
super.onDrawOver(c, parent, state)
c.drawBitmap(BitmapFactory.decodeResource(context.resources, R.drawable.kbo),
500f, 500f, null)
}
// 각각의 item에 대해서 꾸며준다. 근데 recyclerview에서 바로 변경 가능한 부분.
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
super.getItemOffsets(outRect, view, parent, state)
view.setBackgroundColor(Color.parseColor("#123456"))
}
}
'Front-End > Kotlin' 카테고리의 다른 글
[Kotlin] 액티비티 생명주기 (0) | 2024.04.27 |
---|---|
[Kotlin] Material 라이브러리, 플로팅 버튼, Tab 레이아웃, 뷰페이저 (2) | 2024.04.26 |
[Kotlin] Action View 돋보기, 드로어, 토글, Fragment (0) | 2024.04.24 |
[Kotlin] 제트팩 라이브러리, Action Bar 메뉴 (1) | 2024.04.23 |
[Kotlin] Dialog (1) | 2024.04.22 |