목록 화면을 만들 때 사용한다.
아래와 같은 구성 요소를 이용해야 한다.
- ViewHolder(필수) - 항목에 필요한 뷰 객체
- Adapter - 항목을 구성한다. 적절한 데이터를 뷰 객체에 대입
- LayoutManager(필수) - 항목을 배치한다.
- ItemDecoration - 항목을 꾸민다.
<!-- 리사이클러 뷰 등록 -->
<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
<!-- 목록에 표시할 항목 디자인 -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_root"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:id="@+id/item_data"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16dp"/>
</LinearLayout>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding=ActivityMainBinding.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)
}
class MyViewHolder(val binding:ItemMainBinding): 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(ItemMainBinding.inflate(LayoutInflater.from(parent.context)))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {//항목의 뷰를 가지는 뷰 홀더를 준비
val binding=(holder as MyViewHolder).binding
binding.itemData.text=datas[position]
binding.itemRoot.setOnClickListener{
Log.d("kkang","item root click")
}
}
override fun getItemCount(): Int {//항목의 개수를 판단
return datas.size
}
}
MainActivity.kt에 뷰홀더와 어댑터를 작성하고 onCreate 함수에서 리사이클러뷰에 원하는 뷰를 나타낸다.
어댑터로 만든 항목을 리사이클러 뷰에 배치한다.
- LinearLayoutManager: 항목을 가로나 세로 방향으로 배치
- GridLayoutManger: 항목을 그리드로 배치
- StaggeredGridLayoutManager: 항목을 높이가 불규칙한 그리드로 배치
리사이클러 뷰를 꾸밀 때 사용한다.
// ItemDecoration을 상속하여 클래스를 만든다.
class MyDecoration(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.getResources(), R.drawable.intro), 0f, 0f, null)
}
// 모든 항목이 배치된 후 호출
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.img, 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.img),
left.toFloat(),
top.toFloat(),
null
)
}
// 개별 항목을 꾸밀 때 호출
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)
else
outRect.set(10,10,10,0)
view.setBackgroundColor(Color.LTGRAY)
ViewCompat.setElevation(view, 20.0f)
}
}
위의 사진은 onDraw()때, 아래 사진은 onDrawOver()때 그려진다.