리사이클러 뷰- 목록화면 구성
레이아웃 매니저
레이아웃 매니저는 어댑터로 만든 항목을 리사이클러 뷰에 배치합니다. RecyclerView.LayoutManager를 상속받는 클래스로, 라이브러리에서 다음처럼 제공합니다.
함수 | 설명 |
LinearLayoutManager | 항목을 가로나 세로 방향으로 배치합니다. |
GridLayoutManager | 항목을 그리드로 배치합니다. |
StaggeredGridLayoutManager | 항목을 높이가 불규칙한 그리드로 배치합니다. |
항목을 가로·세로 방향으로 배치
LinearLayoutManager를 사용합니다.
항목을 세로로 배치
binding.recyclerView.layoutManager = LinearLayoutManager(this)
항목을 가로로 배치 / LinearLayoutManager의 orientation값을 Linear LayoutManager.HORIZONTAL로 지정
val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
binding.recyclerView.layoutManager = layoutManager
참고
https://developer.android.com/reference/androidx/recyclerview/widget/LinearLayoutManager
그리드로 배치하기
GridLayoutManager를 이용합니다.
항목을 그리드로 배치
val layoutManager = GridLayoutManager(this,2)
binding.recyclerView.layoutManager = layoutManager
생성자의 숫자는 그리드에서 열의 개수를 뜻합니다. GridLayoutManager로 방향을 설정할 수 있습니다. 기본적으로 세로로 배치됩니다.
가로로 설정하려면 생성자에 GridLayoutManager.HORIZONTAL을 지정해줍니다.
val layoutManager = GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false)
binding.recyclerView.layoutManager = layoutManager
GridLayoutManager 생성자의 네 번째 매개변수에 Boolean값을 설정으로 true로 지정하면 세로일때는 아래부터 가로일때는 오른쪽 부터 배치 됩니다.
그리드에서 항목을 오른쪽부터 배치
val layoutManager = GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, )
binding.recyclerView.layoutManager = layoutManager
참고
https://developer.android.com/reference/androidx/recyclerview/widget/GridLayoutManager
높이가 불규칙한 그리드로 배치하기
StaggeredGridLayoutManager는 뷰의 크기가 다르면 지그재그 형태로 배치합니다.
val layoutManager = StaggeredGridLayoutManager (2, StaggeredGridLayoutManager.VERTICAL)
binding.recyclerView.layoutManager = LayoutManager
참고
https://developer.android.com/reference/androidx/recyclerview/widget/StaggeredGridLayoutManager
아이템 데커레이션
아이템 데커레이션은 리사이클러 뷰를 다양하게 꾸밀 때 사용합니다. 아이템 데커레이션은 필수가 아니므로 필요할경우만 적용해주면 됩니다.
라이브러리에서 제공하는 아이템 데코레이션은 항목의 구분선을 출력해 주는 DividerItem Decoration 뿐입니다. 결국 아이템 데커레이션은 데부분 ItemDecoration을 상속받는 개발자 클래스를 만들고 이 클래스에서 다양한 꾸미기 작업을 합니다.
아이템 데커레이션 구현
class MyDecoration(val context: Context): RecyclerView.ItemDecoration() {
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw(c, parent, state)
}
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDrawOver(c, parent, state)
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
}
}
아이템 데커레이 제공하는 함수 | 설명 |
onDraw() | 항목이 배치되기 전에 호출됩니다. |
onDrawOver() | 항목이 모두 배치된 후 호출됩니다. |
getItemOffsets() | 개별 항목을 꾸밀 때 호출됩니다. |
onDraw()함수의 매개변수로 전달되는 캔버스 객체로 각종 그림을 그릴수 있습니다.
항목이 배치되기 전에 호출되는 onDraw()함수
override fun ondraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDraw( c, parent, state)
c.drawBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.stadium),0f, 0f, null)
onDrawOver()함수는 모든 항목이 화면에 배치된 후 호출됩니다. 이 함수의 매개변수로 전달되는 Canvas객체로 그림을 그리면 항목 위에 이 그림을 그리며 항목 위에 이그림이 나타납니다.
override fun onDrawover(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDrawOver(c, parent, state)
// 뷰 크기 계산
val width = parent.width
val height = parent.height
// 이미지 크기 계산
val dr: Drawable? = ResourcesCompat.getDrawable(context.getResources(),
R.drawable.kbo, null)
val drWidth = dr?.intrinsicWidth
val drHeight = dr?.intrinsicHeight
// 이미지가 그려질 위치 계산
val left = width/2 - drWidth?.div(2) as Int
val top = height/2 - drHeight?.div(2) as Int
c.drawBitmap(
BitmapFactory.decodeResource(context.getResources(), R.drawable.kbo),
left.toFloat(),
top.toFloat(),
null
}
}
개별 항목을 꾸미는 getItemOffstets() 함수
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
val index = parent.getChildAdapterPosition(view) + 1
if (index %3 == 0)
outRect.set(10, 10, 10, 60) // left, top, right, bottom
else
outRect.set(10, 10, 10, 0)
view.setBackgroundColor(Color.LTGRAY)
ViewCompat.setElevation(view, 20.0f)
}
아이템 데커레이션 객체를 리사이클러 뷰에 적용할 때는 addItemDecoration() 함수를 이용
binding.recyclerView.addItemDecoration(MyDecoration(this))